mirror of
https://github.com/vrld/HC.git
synced 2024-11-28 14:04:21 +00:00
Merge pull request #31 from Ragzouken/intersectionsRay
method to return all intersections, not just the first
This commit is contained in:
commit
afc917253c
44
polygon.lua
44
polygon.lua
@ -462,6 +462,50 @@ function Polygon:intersectsRay(x,y, dx,dy)
|
|||||||
return tmin ~= math.huge, tmin
|
return tmin ~= math.huge, tmin
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Polygon:intersectionsRay(x,y, dx,dy)
|
||||||
|
--local p = vector(x,y)
|
||||||
|
--local v = vector(dx,dy)
|
||||||
|
local nx,ny = vector.perpendicular(dx,dy)
|
||||||
|
local wx,xy,det
|
||||||
|
|
||||||
|
local ts = {}
|
||||||
|
local q1,q2 = nil, self.vertices[#self.vertices]
|
||||||
|
for i = 1, #self.vertices do
|
||||||
|
q1,q2 = q2,self.vertices[i]
|
||||||
|
wx,wy = q2.x - q1.x, q2.y - q1.y
|
||||||
|
det = vector.det(dx,dy, wx,wy)
|
||||||
|
|
||||||
|
if det ~= 0 then
|
||||||
|
-- there is an intersection point. check if it lies on both
|
||||||
|
-- the ray and the segment.
|
||||||
|
local rx,ry = q2.x - x, q2.y - y
|
||||||
|
local l = vector.det(rx,ry, wx,wy) / det
|
||||||
|
local m = vector.det(dx,dy, rx,ry) / det
|
||||||
|
if m >= 0 and m <= 1 then
|
||||||
|
-- we cannot jump out early here (i.e. when l > tmin) because
|
||||||
|
-- the polygon might be concave
|
||||||
|
table.insert(ts, l)
|
||||||
|
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 = vector.dot(q1.x-x,q1.y-y, nx,ny)
|
||||||
|
if dist == 0 then
|
||||||
|
local l = vector.dot(dx,dy, q1.x-x,q1.y-y)
|
||||||
|
local m = vector.dot(dx,dy, q2.x-x,q2.y-y)
|
||||||
|
if l >= m then
|
||||||
|
table.insert(ts, l)
|
||||||
|
else
|
||||||
|
table.insert(ts, m)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ts
|
||||||
|
end
|
||||||
|
|
||||||
Polygon = common_local.class('Polygon', Polygon)
|
Polygon = common_local.class('Polygon', Polygon)
|
||||||
newPolygon = function(...) return common_local.instance(Polygon, ...) end
|
newPolygon = function(...) return common_local.instance(Polygon, ...) end
|
||||||
return Polygon
|
return Polygon
|
||||||
|
30
shapes.lua
30
shapes.lua
@ -213,6 +213,14 @@ function ConvexPolygonShape:intersectsRay(x,y, dx,dy)
|
|||||||
return self._polygon:intersectsRay(x,y, dx,dy)
|
return self._polygon:intersectsRay(x,y, dx,dy)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function ConcavePolygonShape:intersectionsRay(x,y, dx,dy)
|
||||||
|
return self._polygon:intersectionsRay(x,y, dx,dy)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ConvexPolygonShape:intersectionsRay(x,y, dx,dy)
|
||||||
|
return self._polygon:intersectionsRay(x,y, dx,dy)
|
||||||
|
end
|
||||||
|
|
||||||
-- circle intersection if distance of ray/center is smaller
|
-- circle intersection if distance of ray/center is smaller
|
||||||
-- than radius.
|
-- than radius.
|
||||||
-- with r(s) = p + d*s = (x,y) + (dx,dy) * s defining the ray and
|
-- with r(s) = p + d*s = (x,y) + (dx,dy) * s defining the ray and
|
||||||
@ -240,6 +248,22 @@ function CircleShape:intersectsRay(x,y, dx,dy)
|
|||||||
return true, math_min(s1,s2)/(2*a)
|
return true, math_min(s1,s2)/(2*a)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function CircleShape:intersectionsRay(x,y, dx,dy)
|
||||||
|
local pcx,pcy = x-self._center.x, y-self._center.y
|
||||||
|
|
||||||
|
local a = vector.len2(dx,dy)
|
||||||
|
local b = 2 * vector.dot(dx,dy, pcx,pcy)
|
||||||
|
local c = vector.len2(pcx,pcy) - self._radius * self._radius
|
||||||
|
local discr = b*b - 4*a*c
|
||||||
|
|
||||||
|
if discr < 0 then return {} end
|
||||||
|
|
||||||
|
discr = math_sqrt(discr)
|
||||||
|
local s1, s2 = (discr-b)/(2*a), (-discr-b)/(2*a)
|
||||||
|
|
||||||
|
return {math.min(s1, s2), math.max(s1, s2)}
|
||||||
|
end
|
||||||
|
|
||||||
-- point shape intersects ray if it lies on the ray
|
-- point shape intersects ray if it lies on the ray
|
||||||
function PointShape:intersectsRay(x,y, dx,dy)
|
function PointShape:intersectsRay(x,y, dx,dy)
|
||||||
local px,py = self._pos.x-x, self._pos.y-y
|
local px,py = self._pos.x-x, self._pos.y-y
|
||||||
@ -247,6 +271,12 @@ function PointShape:intersectsRay(x,y,dx,dy)
|
|||||||
return t >= 0, t
|
return t >= 0, t
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function PointShape:intersectionsRay(x,y, dx,dy)
|
||||||
|
local px,py = self._pos.x-x, self._pos.y-y
|
||||||
|
local t = vector.dot(px,py, dx,dy) / vector.len2(dx,dy)
|
||||||
|
return {t}
|
||||||
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- auxiliary
|
-- auxiliary
|
||||||
--
|
--
|
||||||
|
Loading…
Reference in New Issue
Block a user