Just another example of the same thing but using the polystuff library for fancier transformations and a polygon from the polyeditor.

`import "Keycodes.lib"`

import "Math.lib"

import "PolyStuff.lib"

circleX# = 100.0

circleY# = 200.0

circleR# = 32.0

set redraw off

' polygon created with the polygon editor.

pf#[][] = [[-40.0, -180.0], [40.0, -180.0], [20.0, -20.0], [180.0, -40.0], [180.0, 40.0], [20.0, 20.0], [40.0, 180.0], [-40.0, 180.0], [-20.0, 20.0], [-180.0, 40.0], [-180.0, -40.0], [-20.0, -20.0], [-40.0, -180.0]]

' angles for rotation and scaling.

angle# = 0.0

scaleAngle# = 0.0

do

' control sircle.

dx# = 0.0

dy# = 0.0

if keydown(VK_LEFT) then dx# = dx# - 4.0

if keydown(VK_RIGHT) then dx# = dx# + 4.0

if keydown(VK_UP) then dy# = dy# - 4.0

if keydown(VK_DOWN) then dy# = dy# + 4.0

circleX = circleX + dx

circleY = circleY + dy

' update polygon angles.

angle = angle + 0.5

if angle >= 360.0 then angle = angle - 360.0

scaleAngle = scaleAngle + 1.5

if scaleAngle >= 360.0 then scaleAngle = scaleAngle - 360.0

' make a copy of the original polygon and transform it some.

pft#[][] = pf

_ClearTransformation

_Translate 320.0, 240.0

_Rotate angle

_Scale 1.0 + sin(scaleAngle*2.0)*0.25, 1.0 - sin(scaleAngle*1.0)*0.25

_TransformPolygon pft

_ClearTransformation

' perform collision tests.

' the goal is ofcourse to do keep calling CLInt until there are no collisions,

' but some more tweaks need to be made for that to work; sometimes after a

' "vertex push" a collision is still reported which would hang the loop. also

' it would be desirable to test the lines and let them push in some order,

' maybe based on the size of the intersections.

steps = 0

do

collision = false

for i = 0 to sizeof(pft, 0) - 2

if CLInt(circleX, circleY, circleR, pft[i][0], pft[i][1], pft[i + 1][0], pft[i + 1][1])

collision = true

endif

next

steps = steps + 1

until collision = false or steps = 4

' draw.

set color 0, 0, 0

cls

set color 255, 255, 255

_DrawPolygon pft, true

set color 255, 255, 0

draw pixel int(circleX), int(circleY)

for i = 0 to 12

a1# = float(i)*360.0/12.0

a2# = float(i + 1)*360.0/12.0

x1 = int(circleX + cos(a1)*circleR)

y1 = int(circleY + sin(a1)*circleR)

x2 = int(circleX + cos(a2)*circleR)

y2 = int(circleY + sin(a2)*circleR)

draw line x1, y1, x2, y2

next

redraw

wait 16

until keydown(27, true)

function CLInt(&cx#, &cy#, cr#, lx1#, ly1#, lx2#, ly2#)

c#[] = [cx - lx1, cy - ly1]

l#[] = [lx2 - lx1, ly2 - ly1]

lineLen# = V_Size(l)

param#

' p is the clost point ON the line to c.

p#[] = V_ProjectGet2(c, l, param)

' is the projection on the line?

if param >= 0.0 and param <= lineLen

dv#[] = V_SubGet(c, p)

if V_Size(dv) < cr

' dv is actually the normal of the line in the correct direction.

' so we can get the corrected position.

_V_Normalize dv

cx = lx1 + p[0] + dv[0]*cr

cy = ly1 + p[1] + dv[1]*cr

return true

else

return false

endif

' check closest distance to vertices.

else

' closest to first vertex?

if param < 0.0

ed# = DistanceF(cx, cy, lx1, ly1)

if ed < cr

' push out.

dv#[] = [cx - lx1, cy - ly1]

_V_Normalize dv

cx# = lx1 + dv[0]*cr

cy# = ly1 + dv[1]*cr

return true

else

return false

endif

' cosest to second vertex.

else

ed# = DistanceF(cx, cy, lx2, ly2)

if ed < cr

dv#[] = [cx - lx2, cy - ly2]

_V_Normalize dv

cx# = lx2 + dv[0]*cr

cy# = ly2 + dv[1]*cr

return true

else

return false

endif

endif

return false

endif

endfunc

function V_ProjectGet2#[](&u#[], &v#[], &p#)

n#[] = V_NormalizeGet(v)

s# = V_Dot(u, n)

p = s

return [n[0]*s, n[1]*s]

endfunc