So I've been working at this on and off for a week, googling and all and I haven't found how to do this.
I have a table of "rays" and a table of "lines", and I want the lines to act as mirrors and reflect a ray whenever the ray hits a line. Imagine a laser bouncing off mirrors, that sort of reflection. I've got the intersection detection working, but I can't figure out how to properly calculate the angle of reflection and extend the ray that direction.
Code:
--the table rays is a table of tables, and each table inside is formatted as such:
--rays[x] = {100,200,150,600,200,400}, where (100,200) are ordered pairs, etc.
--The table lines simply contains values for x1,y1,x2,y2
for i,ray in ipairs(rays) do
for j,line in ipairs(lines) do
if line.x2 ~= nil and #ray>3 then
print(line.x2..' '..line.y2)
iX, iY = intersect.test(ray[#ray-3],ray[#ray-2],
ray[#ray-1],ray[#ray],line.x1,line.y1,line.x2,line.y2)
--The above code takes each ray and
--sees if it intersects with a line, with the intersect.test function
--Then if it does, where iX and iY aren't nil, it continues
if iX ~= nil and iY ~= nil then
local rayA = (180/math.pi)*math.atan(getSlope(ray[#ray-3],ray[#ray-2],ray[#ray-1],ray[#ray]))
local lineA = (180/math.pi)*math.atan(getSlope(line.x1,line.y1,line.x2,line.y2))
local normalA = (180/math.pi)*math.atan(-1/getSlope(line.x1,line.y1,line.x2,line.y2))
--Here I'm calculating the angle in degrees. For the final code all those atans will
--be out of there for optimization, but its easiest now to see the actual angle
print(rayA..' '..lineA..' '..normalA)
ray[#ray-1]=iX
ray[#ray]=iY
--This little part just create a point on the ray right at the intersection
--The code after this is my attempt, which doesn't work
local reflectA = normalA-rayA
local reflectR = 2*reflectA+rayA
print(reflectR)
reflectR = reflectR/(180/math.pi)
local rSlope = math.tan(reflectR)
local offset = 0
ray[#ray+1]=iX+offset
ray[#ray+1]=iY+(offset*rSlope)
end
end
end
end
I'm stuck on that last section. It sort of creates a segment bouncing off the line, but sometimes it crosses over the line, and it never is the correct reflection angle. Any pointers on how I should do this would be greatly appreciated.
It's better to avoid working with slopes and angles if you can avoid them, because you will have to deal with annoying special cases like when the slope is +ve or -ve infinity and so on.
If you can calculate the normal of the line (blue arrow), then you can use a dot product to do the reflection:
Calculating the normal for the line is done like this:
Then you need to calculate the vector that goes from the intersection point of the line and the ray to the tip of the ray (the point that has gone "through" the line that you want to reflect):
Then calculate the dot product:
This tells us how far in the direction of the line normal the ray has gone past the intersection point (the length of the green line). To find the vector for the green line, multiply the line normal by the dot product:
If we negate this vector and then double it (to get the green line plus the pink line), and add it to the tip of the ray, we will get the reflected tip of the ray: