mirror of
https://github.com/vrld/HC.git
synced 2024-11-18 12:54:23 +00:00
add ray intersection
This commit is contained in:
parent
56737e7aa0
commit
da6e772be7
33
polygon.lua
33
polygon.lua
@ -352,6 +352,39 @@ function Polygon:contains(x,y)
|
||||
return in_polygon
|
||||
end
|
||||
|
||||
function Polygon:intersectsRay(x,y, dx,dy)
|
||||
local p = vector(x,y)
|
||||
local v = vector(dx,dy):normalize_inplace()
|
||||
local n = v:perpendicular()
|
||||
|
||||
local vertices = self.vertices
|
||||
for i = 1, #vertices do
|
||||
local q1, q2 = vertices[i], vertices[ (i % #vertices) + 1 ]
|
||||
local w = q2 - q1
|
||||
local det = v:cross(w)
|
||||
|
||||
if det ~= 0 then
|
||||
-- there is an intersection point. check if it lies on both
|
||||
-- the ray and the segment.
|
||||
local r = q2 - p
|
||||
local l = r:cross(w)
|
||||
local m = v:cross(r)
|
||||
if l >= 0 and m >= 0 and m <= det then return true end
|
||||
else
|
||||
-- lines parralel or incident. get distance of line to
|
||||
-- anchor point. if they are incident, check if an endpoint
|
||||
-- lies on the ray
|
||||
local dist = (q1 - p) * n
|
||||
if dist == 0 then
|
||||
if n:cross(q1) > 0 or n:cross(q2) > 0 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
-- module() as shortcut to module.Polygon()
|
||||
do
|
||||
|
19
shapes.lua
19
shapes.lua
@ -216,6 +216,23 @@ function CircleShape:contains(x,y)
|
||||
return (x - self._center):len2() < self._radius * self._radius
|
||||
end
|
||||
|
||||
|
||||
function ConcavePolygonShape:intersectsRay(x,y, dx,dy)
|
||||
return self._polygon:intersectsRay(x,y, dx,dy)
|
||||
end
|
||||
|
||||
function ConvexPolygonShape:intersectsRay(x,y, dx,dy)
|
||||
return self._polygon:intersectsRay(x,y, dx,dy)
|
||||
end
|
||||
|
||||
-- circle intersection if distance of ray/center is smaller
|
||||
-- than radius
|
||||
function CircleShape:intersectsRay(x,y, dx,dy)
|
||||
local n = vector(-dy,dx):normalize_inplace() -- normal vector
|
||||
local d = vector(x,y) - self._center
|
||||
return d * vector(dx,dy) >= 0 and (d * n) < self._radius
|
||||
end
|
||||
|
||||
--
|
||||
-- auxiliary
|
||||
--
|
||||
@ -311,5 +328,3 @@ function CircleShape:draw(mode, segments)
|
||||
love.graphics.circle(mode, self._center.x, self._center.y, self._radius, segments)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user