REM SOURCES
REM Paul Bourke (http://astronomy.swin.edu.au/~pbourke/geometry/)
REM
REM Coded by: Phaelax
type Vector2D
x as float
y as float
endtype
type Vector3D
x as float
y as float
z as float
endtype
type Line2D
a as Vector2D
b as Vector2D
endtype
type Line3D
a as Vector3D
b as Vector3D
endtype
type Capsule2D
ln as Line2D
radius as float
endtype
type Circle2D
center as Vector2D
radius as float
endtype
type Ellipse2D
center as Vector2D
radius as Vector2D
endtype
rem point on the plane
rem plane's normal
type Plane
p as Vector3D
n as Vector3D
endtype
p as Vector2D
p3 as Vector3D
ln as Line2D
c as Circle2D
e as Ellipse2D
pn as Plane
sync on
DO
cls
set cursor 0,0
print "Press spacebar to initialize test"
`gosub TEST_CX_2D_EllipseLine
`gosub TEST_CX_2D_DistancePointLine
`gosub TEST_CX_2D_PointTriangle
`gosub TEST_CX_2D_CircleLine
sync
LOOP
`==============================================
`
`==============================================
function CX_2D_ReflectVector(v as Vector2D, n as Vector2D)
endfunction
`==============================================
`
`==============================================
function CX_3D_ReflectVector(v as Vector3D, n as Vector3D)
endfunction
`==============================================
`
`==============================================
function CX_3D_LinePlane(ln as Line3D, p as Plane)
endfunction
`==============================================
`Finds intersection time of line[A,b] through
`line[C,D]. If lines intersection, value should
`be in set [0,1]
`==============================================
function CX_2D_LineLine(a as vector2D, b as vector2D, c as vector2D, d as vector2D)
num# = (d.x-c.x)*(a.y-c.y) - (d.y-c.y)*(a.x-c.x)
den# = (d.y-c.y)*(b.x-a.x) - (d.x-c.x)*(b.y-a.y)
Ua# = num# / den#
endfunction Ua#
`==============================================
`Returns the distance between a point(p) and
`a plane(pn)
`This tests against an infinte plane
`==============================================
function CX_3D_DistancePointPlane#(p as Vector3D, pn as Plane)
num# = pn.n.x*(p.x-pn.p.x) + pn.n.y*(p.y-pn.p.y) + pn.n.z*(p.z-pn.p.z)
den# = sqrt(pn.n.x*pn.n.x + pn.n.y*pn.n.y + pn.n.z*pn.n.z)
n# = num# / den#
endfunction n#
`==============================================
`Returns 1 if the ellipse(e) intersects line(ln)
`0 if not
`Converts the problem into a circle/line intersection
`by transforming the space so that the ellipse
`becomes a unit circle
`==============================================
function CX_2D_EllipseLine(e as Ellipse2D, ln as Line2D)
ln.a.x = ln.a.x / e.radius.x
ln.a.y = ln.a.y / e.radius.y
ln.b.x = ln.b.x / e.radius.x
ln.b.y = ln.b.y / e.radius.y
c as Circle2D
c.center.x = e.center.x / e.radius.x
c.center.y = e.center.y / e.radius.y
c.radius = 1
n = CX_2D_CircleLine(c, ln)
endfunction n
`==============================================
`Returns 1 if the circle(c) intersects line(ln)
`0 if not
`==============================================
function CX_2D_CircleLine(c as Circle2D, ln as Line2D)
d# = CX_2D_DistancePointLine#(c.center, ln)
if d# <= c.radius then exitfunction 1
endfunction 0
`==============================================
`Returns 1 if point is inside capsule, 0 if not
`==============================================
function CX_2D_PointCapsule(p as Vector2D, c as Capsule2D)
if CX_2D_DistancePointLine#(p, c.ln) <= c.radius then exitfunction 1
endfunction 0
`==============================================
`Returns the distance between point(P) and
`the line segment(LN). If the point is beyond
`the line's endpoints, then the distance returned
`is that of the point from the nearest endpoint.
`In other words, this does not test an infinte line
`==============================================
function CX_2D_DistancePointLine#(p as Vector2D, ln as Line2D)
n# = (p.x-ln.a.x)*(ln.b.x-ln.a.x) + (p.y-ln.a.y)*(ln.b.y-ln.a.y)
x# = ln.b.x - ln.a.x
y# = ln.b.y - ln.a.y
d# = x#*x# + y#*y#
u# = n# / d#
dist# = 0.0
if u# >= 0 AND u# <= 1
i as Vector2D
i.x = ln.a.x + u#*(ln.b.x-ln.a.x)
i.y = ln.a.y + u#*(ln.b.y-ln.a.y)
dist# = CX_2D_lineLength#(p,i)
else
if u# < 0 then dist# = CX_2D_lineLength#(p,ln.a)
if u# > 1 then dist# = CX_2D_lineLength#(p,ln.b)
endif
endfunction dist#
`==============================================
`Returns the distance between two 2D points
`==============================================
function CX_2D_LineLength#(a as Vector2D, b as Vector2D)
x# = b.x - a.x
y# = b.y - a.y
d# = sqrt(x#*x# + y#*y#)
endfunction d#
`==============================================
`Returns 1 if point is inside triangle, 0 if not
`Point (px,py)
`triangle (x1,y1),(x2,y2),(x3,y3)
`==============================================
function CX_2D_PointTriangle(px as float, py as float, x1 as float,y1 as float,x2 as float,y2 as float,x3 as float,y3 as float)
dABx = x2-x1
dABy = y2-y1
dBCx = x3-x2
dBCy = y3-y2
rem if verts are clockwise
if (dABx*dBCy - dABy*dBCx) < 0
if dABx*(py-y1) >= dABy*(px-x1) then exitfunction 0
if dBCx*(py-y2) >= dBCy*(px-x2) then exitfunction 0
if (x1-x3)*(py-y3) >= (y1-y3)*(px-x3) then exitfunction 0
rem verts are ccw
else
if dABx*(py-y1) < dABy*(px-x1) then exitfunction 0
if dBCx*(py-y2) < dBCy*(px-x2) then exitfunction 0
if (x1-x3)*(py-y3) < (y1-y3)*(px-x3) then exitfunction 0
endif
rem point is inside triangle
endfunction 1
`==============================================
`Returns 1 if boxes overlap, 0 if not
`upper left corner of box A (x1,y1) and width(w1)
`and height(h1)
`upper left corner of box B (x2,y2) and width(w2)
`and height(h2)
`==============================================
function CX_2D_AABB(x1 as float,y1 as float,w1 as float,h1 as float,x2 as float,y2 as float,w2 as float,h2 as float)
if x1 < (x2+w2) and (x1+w1) > x2 and y1 < (y2+h2) and y2 < (y1+h2) then exitfunction 1
endfunction 0
`==============================================
`Returns 1 if circles are overlapping, 0 if not
`Center of circle A (x1,y1), radius (r1)
`Center of circle B (x2,y2), radius (r2)
`==============================================
function CX_2D_CircleCircle(x1 as float, y1 as float r1 as float, x2 as float, y2 as float, r2 as float)
dsqr# = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)
rsqr# = (r1+r2)*(r1+r2)
if dsqr# <= rsqr# then exitfunction 1
endfunction 0
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TEST_CX_2D_DistancePointLine:
p.x = mousex()
p.y = mousey()
if spacekey() and flag = 0
ln.a.x = rnd(640)
ln.a.y = rnd(480)
ln.b.x = rnd(640)
ln.b.y = rnd(480)
flag = 1
endif
if spacekey()=0 then flag = 0
line ln.a.x,ln.a.y,ln.b.x,ln.b.y
set cursor 0,0
print "Distance: ",CX_2D_DistancePointLine#(p,ln)
RETURN
TEST_CX_2D_PointTriangle:
mx = mousex()
my = mousey()
if CX_2D_PointTriangle(mx,my,x1,y1,x2,y2,x3,y3)
ink rgb(255,0,0),0
else
ink rgb(255,255,255),0
endif
if spacekey() and flag = 0
flag = 1
x1 = rnd(640)
y1 = rnd(480)
x2 = rnd(640)
y2 = rnd(480)
x3 = rnd(640)
y3 = rnd(480)
endif
if spacekey()=0 then flag = 0
line x1,y1,x2,y2
line x2,y2,x3,y3
line x3,y3,x1,y1
RETURN
TEST_CX_2D_CircleLine:
c.center.x = mousex()
c.center.y = mousey()
if mouseclick() = 1 then inc c.radius, 1
if mouseclick() = 2 then dec c.radius, 1
if CX_2D_CircleLine(c,ln)
ink rgb(255,0,0),0
else
ink rgb(255,255,255),0
endif
if spacekey() and flag = 0
ln.a.x = rnd(640)
ln.a.y = rnd(480)
ln.b.x = rnd(640)
ln.b.y = rnd(480)
flag = 1
endif
if spacekey()=0 then flag = 0
line ln.a.x,ln.a.y,ln.b.x,ln.b.y
circle c.center.x, c.center.y, c.radius
print "mouse buttons resize circle"
RETURN
TEST_CX_2D_EllipseLine:
e.center.x = mousex()
e.center.y = mousey()
if mouseclick() = 1 then inc e.radius.x, 1
if mouseclick() = 2 then dec e.radius.x, 1
e.radius.y = 20
if CX_2D_EllipseLine(e,ln)
ink rgb(255,0,0),0
else
ink rgb(255,255,255),0
endif
if spacekey() and flag = 0
ln.a.x = rnd(640)
ln.a.y = rnd(480)
ln.b.x = rnd(640)
ln.b.y = rnd(480)
flag = 1
endif
if spacekey()=0 then flag = 0
line ln.a.x,ln.a.y,ln.b.x,ln.b.y
ellipse e.center.x, e.center.y, e.radius.x, e.radius.y
print "mouse buttons resize ellipse on X"
RETURN