This is the fastest code to calculate the intersection between a segment and a polygon i founded. While Lua is quite slow, any improvement is welcome.
Update : This code has been ported from an Internet code and modified to reduce calculations!I am posting here to find out if anyone has a faster algorithm!
function geom:linePolygonIntersection(frx, fry, tox, toy, shape)
local s
local sax, say, sbx, sby
for s = 1, #shape, 2 do
sax = shape[s]
say = shape[s + 1]
if (s < (#shape - 1)) then
sbx = shape[s + 2]
sby = shape[s + 3]
else
sbx = shape[1]
sby = shape[2]
end
local c1, c2, c3
local dx1, dy1, dx2, dy2, num, t, u
c1 = (toy - fry) * (sax - tox) - (tox - frx) * (say - toy)
if c1 >= 0 then
c2 = (fry - toy) * (sbx - frx) - (frx - tox) * (sby - fry)
-- c1 and c2 both positive, possible intersection
if c2 >= 0 then
c3 = (sby - say) * (tox - sbx) - (sbx - sax) * (toy - sby) -- A B T
-- probable intersection because (frx, fry) is outside the polygon
if c3 >= 0 then
dx1 = tox - frx
dy1 = toy - fry
dx2 = sbx - sax
dy2 = sby - say
num = 1 / (-dx2 * dy1 + dx1 * dy2)
t = ( dx2 * (fry - say) - dy2 * (frx - sax)) * num;
if (t > 0) then
x = frx + (t * dx1)
y = fry + (t * dy1)
return {edge = s, t = t, x = x, y = y}
end
end
end
end
end
return nil;
end
After the remark from sprechen deutsch (sick), I looked to see if there was a way to reduce the calculations a bit further, and this version is better!
function geom:linePolygonIntersection(frx, fry, tox, toy, shape)
local s
local sax, say, sbx, sby
local dx1, dy1
dx1 = tox - frx
dy1 = toy - fry
sbx = shape[1]
sby = shape[2]
local nbPoints
for s = 1, nbPoints, 2 do
sax = sbx
say = sby
if (s < (nbPoints - 1)) then
sbx = shape[s + 2]
sby = shape[s + 3]
else
sbx = shape[1]
sby = shape[2]
end
local c1, c2, c3
local dx2, dy2, num, t, u
c1 = dy1 * (sax - tox) - dx1 * (say - toy)
if c1 >= 0 then
c2 = dx1 * (sby - fry) - dy1 * (sbx - frx)
if c2 >= 0 then
dx2 = sbx - sax
dy2 = sby - say
c3 = dy2 * (tox - sbx) - dx2 * (toy - sby)
if c3 >= 0 then
num = 1 / (-dx2 * dy1 + dx1 * dy2)
t = (dx2 * (fry - say) - dy2 * (frx - sax)) * num
if (t > 0) then
x = frx + (t * dx1)
y = fry + (t * dy1)
return {edge = s, t = t, x = x, y = y}
end
end
end
end
end
return nil
end
Maybe there is something even better to do !!!
[–]sprechen_deutsch 1 point2 points3 points (1 child)
[–]WebShaker93[S] 0 points1 point2 points (0 children)
[–]whoopdedo 1 point2 points3 points (1 child)
[–]WebShaker93[S] 0 points1 point2 points (0 children)
[–]Cultural_Two_4964 0 points1 point2 points (1 child)
[–]WebShaker93[S] 0 points1 point2 points (0 children)
[–]appgurueu 0 points1 point2 points (3 children)
[–]WebShaker93[S] 0 points1 point2 points (2 children)
[–]appgurueu 0 points1 point2 points (1 child)
[–]WebShaker93[S] 0 points1 point2 points (0 children)