Here is an example showing some points bouncing around inside and outside a polygon. the functions may be useful for something like a pee wee golf game? the polygon was exported from the polygon editor program, i do not remember who wrote it.
rem poly bounce.
rem by jsm.
import "Math.lib"
import "Speed.lib"
rem exported from polygon editor.
poly[][] = [[-140,160], [-80,40], [-140,-60], [-20,-60], [-40,-160], [120,-140], [60,20], [180,100], [60,160], [20,60]]
rem convert to screen coords and make a float duplicate.
points = sizeof(poly, 0)
polyf#[points][4]
for i = 0 to points - 1
poly[i][0] = 640*(poly[i][0] + 200)/400
poly[i][1] = 480*(poly[i][1] + 200)/400
polyf[i][0] = float(poly[i][0])
polyf[i][1] = float(poly[i][1])
next
rem vectors between points in closed polygon.
for i = 0 to points - 1
polyf[i][2] = float(poly[(i + 1)%points][0] - poly[i][0])
polyf[i][3] = float(poly[(i + 1)%points][1] - poly[i][1])
next
rem init a couple of bouncers.
bouncers?[500]
for i = 0 to sizeof(bouncers) - 1
bouncers[i] = NewBouncer(float(rnd(640)), float(rnd(480)), float(rnd(360)), 8.0*float(rnd(75) + 25)/100.0)
next
rem uh, return a new bouncer.
function NewBouncer?(x#, y#, angle#, spd#)
b?.x# = x
b.y# = y
b.dx# = cos(angle)
b.dy# = sin(angle)
b.spd# = spd
return b
endfunc
set redraw off
do
rem move bouncers.
for i = 0 to sizeof(bouncers, 0) - 1
proc MoveBouncer bouncers[i], polyf
next
rem draw.
set color 0, 0, 0
cls
set color 255, 255, 255
proc DrawPoly poly
set color 255, 255, 0
for i = 0 to sizeof(bouncers, 0) - 1
draw pixel int(bouncers[i].x#), int(bouncers[i].y#)
next
redraw
proc SPD_HoldFrame 60
until keydown(27, true)
rem move bouncers. hope you know your linear algebra :)
procedure MoveBouncer(&bouncer?, &p#[][])
px# = bouncer.x#
py# = bouncer.y#
dx# = bouncer.dx#*bouncer.spd#
dy# = bouncer.dy#*bouncer.spd#
pointCount = sizeof(p, 0)
prevHit = -1
do
hadCollision = false
minParam# = 2.0
minPoint = -1
for i = 0 to pointCount - 1
if i <> prevHit
param# = RayLineIntersection(px, py, dx, dy, p[i][0], p[i][1], p[i][2], p[i][3])
if param >= 0.0 and param < minParam
minParam = param
minPoint = i
endif
endif
next
if minParam <= 1.0
hadCollision = true
prevHit = minPoint
px = px + dx*minParam
py = py + dy*minParam
r#[] = [dx, dy]
l#[] = [p[minPoint][2], p[minPoint][3]]
v#[] = V_ReflectGet(r, l)
proc V_Scale v, (minParam)
dx = v[0]
dy = v[1]
else
px = px + dx
py = py + dy
endif
until not hadCollision
bouncer.x# = px#
bouncer.y# = py#
k# = 1.0/sqr(dx*dx + dy*dy)
bouncer.dx# = dx*k
bouncer.dy# = dy*k
endproc
rem detect intersection between positive ray and line segment.
rem if there is an intersection, the parameter of the
rem intersection for the ray is returned, else -1.
function RayLineIntersection#(rx#, ry#, rdx#, rdy#, lx#, ly#, ldx#, ldy#)
dx# = rx - lx
dy# = ry - ly
d# = rdx*ldy - rdy*ldx
if d = 0.0 then return -1.0
u# = (dy*rdx - dx*rdy)/d
if u < 0.0 or u > 1.0 then return -1.0
v# = (dy*ldx - dx*ldy)/d
if v < 0.0 then return -1.0
return v
endfunc
procedure DrawPoly(&poly[][])
s = sizeof(poly, 0)
for i = 0 to s - 1
draw line poly[i][0], poly[i][1], poly[(i + 1)%s][0], poly[(i + 1)%s][1]
next
endproc