Math a";“镜子”;

Math a";“镜子”;,math,lua,love2d,Math,Lua,Love2d,所以我已经断断续续地工作了一个星期,用谷歌搜索等等,但我还没有找到如何做到这一点 我有一张“光线”表和一张“线”表,我希望这些线可以像镜子一样,在光线碰到线时反射光线。想象一下,一个激光从镜子上反弹,这种反射。我已经完成了交叉点检测,但是我不知道如何正确地计算反射角度并将光线延伸到该方向 代码: --the table rays is a table of tables, and each table inside is formatted as such: --rays[x] = {100,2

所以我已经断断续续地工作了一个星期,用谷歌搜索等等,但我还没有找到如何做到这一点

我有一张“光线”表和一张“线”表,我希望这些线可以像镜子一样,在光线碰到线时反射光线。想象一下,一个激光从镜子上反弹,这种反射。我已经完成了交叉点检测,但是我不知道如何正确地计算反射角度并将光线延伸到该方向

代码:

--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

我被困在最后一节了。它在某种程度上创建了一个从直线上反弹的线段,但有时它会穿过直线,并且它从来都不是正确的反射角度。任何关于我应该如何做的建议都将不胜感激。

如果可以避免的话,最好避免使用坡度和角度,因为你将不得不处理恼人的特殊情况,如坡度为+ve或-ve无穷大等

如果可以计算线的法线(蓝色箭头),则可以使用点积进行反射:

计算直线的法线的方法如下:

local normalY = line.x2 - line.x1
local normalX = line.y1 - line.y2
local normalLength = math.sqrt(normalX * normalX + normalY * normalY)
normalX = normalX / normalLength
normalY = normalY / normalLength
然后,您需要计算从直线和光线的交点到光线尖端(穿过要反射的直线的点)的向量:

然后计算点积:

local dotProduct = (rayX * normalX) + (rayY * normalY)
 local dotNormalX = dotProduct * normalX
 local dotNormalY = dotProduct * normalY
这告诉我们光线在法线方向上经过交点的距离(绿线的长度)。要找到绿线的矢量,请将线法线乘以点积:

local dotProduct = (rayX * normalX) + (rayY * normalY)
 local dotNormalX = dotProduct * normalX
 local dotNormalY = dotProduct * normalY
如果我们对该向量求反,然后将其加倍(以获得绿线加上粉红线),并将其添加到光线的尖端,我们将获得光线的反射尖端:

 local reflectedRayTipX = rayTipX - (dotNormalX * 2)
 local reflectedRayTipY = rayTipY - (dotNormalY * 2)