mirror of
https://github.com/vrld/HC.git
synced 2024-11-18 12:54:23 +00:00
Rename intersectionsRay. Less redundancy.
* intersectionsRay() -> intersectionsWithRay() * intersectsRay() uses results from intersectionsWithRay() (Exception: PointShape does it the other way around)
This commit is contained in:
parent
afc917253c
commit
6bb4ba0e24
63
polygon.lua
63
polygon.lua
@ -419,56 +419,11 @@ 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)
|
||||
function Polygon:intersectionsWithRay(x,y, dx,dy)
|
||||
local nx,ny = vector.perpendicular(dx,dy)
|
||||
local wx,xy,det
|
||||
|
||||
local tmin = math.huge
|
||||
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 l >= 0 and m >= 0 and m <= 1 then
|
||||
-- we cannot jump out early here (i.e. when l > tmin) because
|
||||
-- the polygon might be concave
|
||||
tmin = math.min(tmin, 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 >= 0 and l >= m then
|
||||
tmin = math.min(tmin, l)
|
||||
elseif m >= 0 then
|
||||
tmin = math.min(tmin, m)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return tmin ~= math.huge, tmin
|
||||
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 ts = {} -- ray parameters of each intersection
|
||||
local q1,q2 = nil, self.vertices[#self.vertices]
|
||||
for i = 1, #self.vertices do
|
||||
q1,q2 = q2,self.vertices[i]
|
||||
@ -484,7 +439,7 @@ function Polygon:intersectionsRay(x,y, dx,dy)
|
||||
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)
|
||||
ts[#ts+1] = l
|
||||
end
|
||||
else
|
||||
-- lines parralel or incident. get distance of line to
|
||||
@ -495,9 +450,9 @@ function Polygon:intersectionsRay(x,y, dx,dy)
|
||||
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)
|
||||
ts[#ts+1] = l
|
||||
else
|
||||
table.insert(ts, m)
|
||||
ts[#ts+1] = m
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -506,6 +461,14 @@ function Polygon:intersectionsRay(x,y, dx,dy)
|
||||
return ts
|
||||
end
|
||||
|
||||
function Polygon:intersectsRay(x,y, dx,dy)
|
||||
local tmin = math.huge
|
||||
for _, t in ipairs(self:intersectionsWithRay(x,y,dx,dy)) do
|
||||
tmin = math.min(tmin, t)
|
||||
end
|
||||
return tmin ~= math.huge, tmin
|
||||
end
|
||||
|
||||
Polygon = common_local.class('Polygon', Polygon)
|
||||
newPolygon = function(...) return common_local.instance(Polygon, ...) end
|
||||
return Polygon
|
||||
|
50
shapes.lua
50
shapes.lua
@ -213,12 +213,12 @@ function ConvexPolygonShape:intersectsRay(x,y, dx,dy)
|
||||
return self._polygon:intersectsRay(x,y, dx,dy)
|
||||
end
|
||||
|
||||
function ConcavePolygonShape:intersectionsRay(x,y, dx,dy)
|
||||
return self._polygon:intersectionsRay(x,y, dx,dy)
|
||||
function ConcavePolygonShape:intersectionsWithRay(x,y, dx,dy)
|
||||
return self._polygon:intersectionsWithRay(x,y, dx,dy)
|
||||
end
|
||||
|
||||
function ConvexPolygonShape:intersectionsRay(x,y, dx,dy)
|
||||
return self._polygon:intersectionsRay(x,y, dx,dy)
|
||||
function ConvexPolygonShape:intersectionsWithRay(x,y, dx,dy)
|
||||
return self._polygon:intersectionsWithRay(x,y, dx,dy)
|
||||
end
|
||||
|
||||
-- circle intersection if distance of ray/center is smaller
|
||||
@ -228,27 +228,7 @@ end
|
||||
-- solving [with c = (cx,cy)]:
|
||||
--
|
||||
-- d*d s^2 + 2 d*(p-c) s + (p-c)*(p-c)-r^2 = 0
|
||||
function CircleShape:intersectsRay(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 false end
|
||||
|
||||
discr = math_sqrt(discr)
|
||||
local s1,s2 = discr-b, -discr-b
|
||||
if s1 < 0 then -- first solution is off the ray
|
||||
return s2 >= 0, s2/(2*a)
|
||||
elseif s2 < 0 then -- second solution is off the ray
|
||||
return s1 >= 0, s1/(2*a)
|
||||
end
|
||||
-- both solutions on the ray
|
||||
return true, math_min(s1,s2)/(2*a)
|
||||
end
|
||||
|
||||
function CircleShape:intersectionsRay(x,y, dx,dy)
|
||||
function CircleShape:intersectionsWithRay(x,y, dx,dy)
|
||||
local pcx,pcy = x-self._center.x, y-self._center.y
|
||||
|
||||
local a = vector.len2(dx,dy)
|
||||
@ -259,9 +239,18 @@ function CircleShape:intersectionsRay(x,y, dx,dy)
|
||||
if discr < 0 then return {} end
|
||||
|
||||
discr = math_sqrt(discr)
|
||||
local s1, s2 = (discr-b)/(2*a), (-discr-b)/(2*a)
|
||||
local ts, t1, t2 = {}, discr-b, -discr-b
|
||||
if t1 >= 0 then ts[#ts+1] = t1/(2*a) end
|
||||
if t2 >= 0 then ts[#ts+1] = t2/(2*a) end
|
||||
return ts
|
||||
end
|
||||
|
||||
return {math.min(s1, s2), math.max(s1, s2)}
|
||||
function CircleShape:intersectsRay(x,y, dx,dy)
|
||||
local tmin = math_huge
|
||||
for _, t in ipaits(self:intersectionsWithRay(x,y,dx,dy)) do
|
||||
tmin = math_min(t, tmin)
|
||||
end
|
||||
return tmin ~= math_huge, tmin
|
||||
end
|
||||
|
||||
-- point shape intersects ray if it lies on the ray
|
||||
@ -271,10 +260,9 @@ function PointShape:intersectsRay(x,y, dx,dy)
|
||||
return t >= 0, t
|
||||
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}
|
||||
function PointShape:intersectionsWithRay(x,y, dx,dy)
|
||||
local intersects, t = self:intersectsRay(x,y, dx,dy)
|
||||
return intersects and {t} or {}
|
||||
end
|
||||
|
||||
--
|
||||
|
Loading…
Reference in New Issue
Block a user