Posts: 460
Threads: 61
Joined: Nov 2023
Reputation:
3
It's been 2 years since Marcus introduced this polygon - circle line collision, and it still has me wondering. I keep staring at it, trying to figure out what it's actually supposed to be. It's probably just a quick test model again
Code: #win32
set window "Collision", 640, 480
set redraw off
'Vertices
v = []
v.square = [-50, -50, 50, -50, 50, 50, -50, 50]
v.star = [0, -100, 25, -25, 100, 0, 25, 25, 0, 100, -25, 25, -100, 0, -25, -25]
v.rectangle = [0, 0, 129, 0, 129, 31, 0, 31]
v.tmp1 = [0, 0, 200, 0, 200, 31, 0, 31]
v.tmp2 = [0, 0, 31, 0, 31, 415, 0, 415]
v.cross = [-19,-59, -19,-19, -59,-19, -59,20, -19,20, -19,60, 20,60, 20,20, 60,20, 60,-19, 20,-19, 20,-59]
visible lines = []
filledPolys = []
' MakePoly(verts, x, y, r, g, b, lines, renderList)
square = MakePoly(v.square, 320, 240, 255, 100, 100, lines, filledPolys)
star = MakePoly(v.star, 425, 100, 100, 255, 100, lines, filledPolys)
cross = MakePoly(v.cross, 175, 125, 100, 100, 255, lines, filledPolys)
rectangle = MakePoly(v.rectangle, 110, 300, 100, 255, 255, lines, filledPolys)
rectangle2 = MakePoly(v.rectangle, 425, 300, 100, 255, 255, lines, filledPolys)
tmp1 = MakePoly(v.tmp1, 50, 416, 255, 100, 255, lines, filledPolys)
tmp2 = MakePoly(v.tmp2, 32, 32, 255, 100, 255, lines, filledPolys)
'Balls
visible objs = []
ballCount = 0
objs[ballCount] = Object(rnd(0,width()), 0, 16)
'-----------
' Main Loop
'-----------
while not keydown(KEY_ESCAPE, true)
' Clear screen
set color 0, 0, 0; cls
' Draw grid
set color 64, 64, 64
for gx = 0 to 640 step 64 draw line gx, 0, gx, 480
for gy = 0 to 480 step 64 draw line 0, gy, 640, gy
' Rotate obstacles: + = clockwise, - = counter-clockwise
square.SetAngle(square.Angle() + rad(0.5))
star.SetAngle(star.Angle() + rad(0.25))
cross.SetAngle(cross.Angle() - rad(0.5))
rectangle.SetAngle(rectangle.Angle() - rad(0.25))
rectangle2.SetAngle(rectangle2.Angle() + rad(0.25))
' draw obstacles
foreach polygn in filledPolys polygn.DrawFilled()
' coordinate labels, infobox
set color 255, 255, 255
shapes = [square,star,cross,rectangle,rectangle2,tmp1,tmp2]
for i = 0 to sizeof(shapes)-1
DrawCoordLabel(shapes[i])
next
set caret width()/2+100, height()-50; center "Press ENTER for more balls"
' balls
foreach ball in objs
UpdateObject(ball)
DrawObject(ball)
next
i = 0
while i < ballCount - 1
j = i + 1
while j < ballCount
ResolveBallCollision(objs[i], objs[j])
j = j + 1
wend
i = i + 1
wend
'Drop ball
if keydown(KEY_RETURN,true) then
objs[ballCount] = Object(rnd(0,width()), 0, 16)
ballCount = ballCount + 1
endif
redraw
fwait 60
wend
'------------
' Functions
'------------
function Object(x, y, r)
return [x: x, y: y, r: r, rsqr: r*r, dx: 0, dy: 0, pdx: 0, pdy: 0]
endfunc
' Draw ball
function DrawObject(obj)
set color 255, 255, 0
draw ellipse obj.x, obj.y, obj.r, obj.r, true
endfunc
' Update ball
function UpdateObject(obj)
obj.dy = obj.dy + 0.1
if obj.dy > 6 then obj.dy = 6
' Update position
obj.x = obj.x + obj.dx
obj.y = obj.y + obj.dy
' Collision detection
PushOut(obj, lines)
endfunc
' ResolveBallCollision
function ResolveBallCollision(b1, b2)
dx = b2.x - b1.x; dy = b2.y - b1.y
distSq = dx*dx + dy*dy
minDist = b1.r + b2.r
minDistSq = minDist * minDist
' Early exit if no collision or zero distance
if distSq >= minDistSq or distSq = 0 then return
dist = sqr(distSq)
' push apart
overlap = minDist - dist
b1.x = b1.x - overlap; b1.y = b1.y - overlap
b2.x = b2.x + overlap; b2.y = b2.y + overlap
endfunc
' PushOut: collision resolution
function PushOut(obj, lines)
for i = 1 to 4
col = false
foreach ln in lines
dp = max(0, min(ln[6], (obj.x - ln[0])*ln[4] + (obj.y - ln[1])*ln[5]))
px = ln[0] + dp*ln[4]; py = ln[1] + dp*ln[5]
dx = obj.x - px; dy = obj.y - py
d = dx*dx + dy*dy
if d < obj.rsqr
k = 1/sqr(d)
obj.x = px + dx*k*obj.r
obj.y = py + dy*k*obj.r
obj.dx = obj.dx + 0.5 * dx*k
obj.dy = obj.dy + 0.5 * dy*k
col = true
endif
next
if not col break
next
endfunc
' Polygon
function Polygon(points, x, y, r, g, b)
p = [trans: unset, org: [], verts: [], x: x, y: y, a: 0, cx: 0, cy: 0, r: r, g: g, b: b]
pcount = sizeof(points)/2
' Store original vertices
for i = 0 to pcount - 1
p.verts[sizeof(p.verts)] = points[i*2]
p.verts[sizeof(p.verts)] = points[i*2 + 1]
next
' collision lines
n = pcount - 1
for i = 0 to n
j = (i + 1)%pcount
p.org[sizeof(p.org)] = Line(
points[i*2], points[i*2 + 1],
points[j*2], points[j*2 + 1])
next
for i = 0 to pcount - 1
p.cx = p.cx + points[i*2]; p.cy = p.cy + points[i*2 + 1]
next
p.cx = p.cx/pcount; p.cy = p.cy/pcount
p.trans = copy(p.org)
p.AddTo = function(lines)
foreach ln in .trans lines[sizeof(lines)] = ln
endfunc
p.X = function(); return .x ;endfunc
p.Y = function(); return .y ;endfunc
p.Angle = function(); return .a ;endfunc
p.SetTransform = function(x, y, angle)
.x = x; .y = y; .a = angle; .Transform()
endfunc
p.SetPosition = function(x, y)
.x = x; .y = y; .Transform()
endfunc
p.SetAngle = function(angle)
.a = angle; .Transform()
endfunc
p.Transform = function()
RotateLines(.org, .trans, .cx, .cy, .a)
foreach ln in .trans
ln[0] = ln[0] + .x; ln[1] = ln[1] + .y
ln[2] = ln[2] + .x; ln[3] = ln[3] + .y
ln[4] = (ln[2] - ln[0])/ln[6]; ln[5] = (ln[3] - ln[1])/ln[6]
next
endfunc
p.DrawFilled = function()
set color .r, .g, .b
vcount = sizeof(.verts)/2
polyArgs = []
for i = 0 to vcount - 1
vx = .verts[i*2] - .cx; vy = .verts[i*2 + 1] - .cy
' Apply rotation
rx = vx*cos(.a) - vy*sin(.a)
ry = vx*sin(.a) + vy*cos(.a)
polyArgs[sizeof(polyArgs)] = rx + .cx + .x
polyArgs[sizeof(polyArgs)] = ry + .cy + .y
next
draw poly polyArgs, true
endfunc
p.Transform()
return p
function RotateLines(srcLines, dstLines, aroundX, aroundY, angle)
c = cos(angle); s = sin(angle)
for i = 0 to sizeof(srcLines) - 1
srcLn = srcLines[i]; dstLn = dstLines[i]
x = srcLn[0] - aroundX; y = srcLn[1] - aroundY
dstLn[0] = aroundX + x*c - y*s; dstLn[1] = aroundY + y*c + x*s
x = srcLn[2] - aroundX; y = srcLn[3] - aroundY
dstLn[2] = aroundX + x*c - y*s; dstLn[3] = aroundY + y*c + x*s
next
endfunc
endfunc
function Line(x0, y0, x1, y1)
ln = [x0, y0, x1, y1]
dx = ln[2] - ln[0]; dy = ln[3] - ln[1]
ln[6] = sqr(dx*dx + dy*dy)
ln[4] = dx/ln[6]
ln[5] = dy/ln[6]
return ln
endfunc
function MakePoly(verts, x, y, r, g, b, lines, renderList)
p = Polygon(verts, x, y, r, g, b)
p.AddTo(lines)
renderList[sizeof(renderList)] = p
return p
endfunc
function DrawCoordLabel(p)
set caret p.X(), p.Y()
wln "X"
wln (int(p.X())) + "," + (int(p.Y()))
endfunc
Posts: 196
Threads: 15
Joined: Dec 2023
Reputation:
8
05-16-2026, 01:59 PM
Nice adaptation. I did however notice that there can be an issue if too many balls are introduced, where the balls will start to get trapped inside of the objects, and the program starts to slow down. For the slow down issue, perhaps it just needs a line or two to remove the balls from the table if they move off screen?
Posts: 706
Threads: 92
Joined: Nov 2023
Reputation:
7
Posts: 460
Threads: 61
Joined: Nov 2023
Reputation:
3
(05-16-2026, 01:59 PM)kevin Wrote: Nice adaptation. I did however notice that there can be an issue if too many balls are introduced, where the balls will start to get trapped inside of the objects, and the program starts to slow down. For the slow down issue, perhaps it just needs a line or two to remove the balls from the table if they move off screen?
Thanks a lot for trying out the code and spotting those bugs and performance issues! I really appreciate the feedback. I actually knew about some of them, but I haven't quite figured out the best solution yet. I'm going to do some more digging and will let you know once I find a fix. if anyone else wants to take a look and lend a hand, I would be so grateful for the help!
Posts: 756
Threads: 78
Joined: Nov 2023
Reputation:
8
05-17-2026, 03:41 AM
(This post was last modified: 05-17-2026, 03:44 AM by johnno56.)
I am purely guessing here... I noticed that the balls are very, what's the word, "jittery" when they collide with a surface and I think that this may be the cause of getting "trapped". With most collision routines, like circles and circles, rectangles and circles etc, the routines "assume" that the objects are "solid" ie: defined by strict boundaries.
This is where I am guessing...
The drawn polygons are just a series of connected lines with a filled interior. The "surface" of the polygon is one pixel thick. Not what I would classify as "solid" per se. Combine the speed of the ball and the time it would take to calculate the collision with a line, the ball has already started moving "through" the line when it realizes that it's moved too far and tries to "jump" back. Now, multiply the events by many balls, and thus introducing "lag" and thus "allowing" the ball enough time to pass through the line... until it is presented with another line of the same polygon. It then bounces around within the polygon... That's my guess. Solution: Use "solid" shapes or write collision routines for each specific polygon.
Logic is the beginning of wisdom.
Live long and prosper.
Posts: 196
Threads: 15
Joined: Dec 2023
Reputation:
8
05-17-2026, 10:20 AM
(This post was last modified: 05-17-2026, 10:41 AM by kevin.)
Hi, I am having a quick look at the code. However, I just noticed another little bug - when you add a second ball the first one disappears? I think this only happens the first time a ball is added.
I will have a look at this also, but I will probably have more time tomorrow. Please let us all know if anyone makes any progress on this.
All the best - Kevin.
edit - The disappearing ball is fixed by adding this line after the first ball is created at about line 30:
ballCount = ballCount + 1
Posts: 460
Threads: 61
Joined: Nov 2023
Reputation:
3
05-18-2026, 03:51 AM
(This post was last modified: 05-18-2026, 04:59 AM by 1micha.elok.)
(05-17-2026, 10:20 AM)kevin Wrote: Hi, I am having a quick look at the code. However, I just noticed another little bug - when you add a second ball the first one disappears? I think this only happens the first time a ball is added.
I will have a look at this also, but I will probably have more time tomorrow. Please let us all know if anyone makes any progress on this.
All the best - Kevin.
edit - The disappearing ball is fixed by adding this line after the first ball is created at about line 30:
ballCount = ballCount + 1
Thank you, I'm really glad you found the solution. I completely missed that line. This week, I'm continuing to work through the code to figure out a couple of other bugs.
For performance issue, I think this additional code to remove out-of-bounds balls will solve it...let's see....
Code: ' balls
foreach ball in objs
UpdateObject(ball)
DrawObject(ball)
next
' Remove out-of-bounds balls to prevent unnecessary collision checks
i = 0
while i < ballCount
if objs[i].x > 690 or objs[i].x < -50 or objs[i].y > 530
j = i
while j < ballCount - 1
objs[j] = objs[j + 1]
j = j + 1
wend
ballCount = ballCount - 1
else
i = i + 1
endif
wend
Posts: 196
Threads: 15
Joined: Dec 2023
Reputation:
8
Great, I can test this later on my older computer to see the performance increase.
Posts: 196
Threads: 15
Joined: Dec 2023
Reputation:
8
(05-18-2026, 03:51 AM)1micha.elok Wrote: (05-17-2026, 10:20 AM)kevin Wrote: Hi, I am having a quick look at the code. However, I just noticed another little bug - when you add a second ball the first one disappears? I think this only happens the first time a ball is added.
I will have a look at this also, but I will probably have more time tomorrow. Please let us all know if anyone makes any progress on this.
All the best - Kevin.
edit - The disappearing ball is fixed by adding this line after the first ball is created at about line 30:
ballCount = ballCount + 1
Thank you, I'm really glad you found the solution. I completely missed that line. This week, I'm continuing to work through the code to figure out a couple of other bugs.

For performance issue, I think this additional code to remove out-of-bounds balls will solve it...let's see....
Code: ' balls
foreach ball in objs
UpdateObject(ball)
DrawObject(ball)
next
' Remove out-of-bounds balls to prevent unnecessary collision checks
i = 0
while i < ballCount
if objs[i].x > 690 or objs[i].x < -50 or objs[i].y > 530
j = i
while j < ballCount - 1
objs[j] = objs[j + 1]
j = j + 1
wend
ballCount = ballCount - 1
else
i = i + 1
endif
wend
Thanks for this. It certainly helps, but I am still having performance issues on my older laptop. It would be interesting to hear how the fix is working on more powerful computers.
My specs - a 16 year old laptop running Intel i5 cpu, 4 gb ram, Windows 7 x64.
This laptop, with the preformance fix, still dips below 10 fps when there are a lot of balls on screen (over 170 balls). The fix does mean that the fps goes back to respectable levels when the balls are removed,which is great.
I can see that the fix above does eliminate unnecessary checking once balls move off screen, but the overall table size does not reduce - it will always be the same size as the largest number of balls previously on screen. I don't believe that this has any significant impact on performance however.
One way that I was able to get respectable performance, was to limit the number of balls that can be created by changing the lines where this happens to:
Code: if keydown(KEY_RETURN,true) and ballCount < 32
objs[ballCount] = Object(rnd(0,width()), 0, 16)
ballCount = ballCount + 1
endif
Limiting the number of balls to 32 at any one time gave me a fps consistently above 100 on my dinosaur of a computer.
Another way may be to perhaps add a timer, so that only a certain number of balls van be created every second? The best way around this of course will be to get a true performance increase without restricting the number of balls, but I for one cannot think how to do that at the moment.
I'll add the amended program here, which includes fps calculation, and a way of toggling your performance fix on and off by pressing the R key. I have changed the fwait from 60 to 300 to allow a better picture of what the fps is, and I have removed the limiter for 32 balls shown above. Some information appears at the top of the screen now (fps, ballCount, array size, and whether the routine to remove off-screen balls is active).
It will be interesting to see what performance others are getting.
Code: #win32
set window "Collision", 640, 480
set redraw off
'Vertices
v = []
v.square = [-50, -50, 50, -50, 50, 50, -50, 50]
v.star = [0, -100, 25, -25, 100, 0, 25, 25, 0, 100, -25, 25, -100, 0, -25, -25]
v.rectangle = [0, 0, 129, 0, 129, 31, 0, 31]
v.tmp1 = [0, 0, 200, 0, 200, 31, 0, 31]
v.tmp2 = [0, 0, 31, 0, 31, 415, 0, 415]
v.cross = [-19,-59, -19,-19, -59,-19, -59,20, -19,20, -19,60, 20,60, 20,20, 60,20, 60,-19, 20,-19, 20,-59]
visible lines = []
filledPolys = []
' MakePoly(verts, x, y, r, g, b, lines, renderList)
square = MakePoly(v.square, 320, 240, 255, 100, 100, lines, filledPolys)
star = MakePoly(v.star, 425, 100, 100, 255, 100, lines, filledPolys)
cross = MakePoly(v.cross, 175, 125, 100, 100, 255, lines, filledPolys)
rectangle = MakePoly(v.rectangle, 110, 300, 100, 255, 255, lines, filledPolys)
rectangle2 = MakePoly(v.rectangle, 425, 300, 100, 255, 255, lines, filledPolys)
tmp1 = MakePoly(v.tmp1, 50, 416, 255, 100, 255, lines, filledPolys)
tmp2 = MakePoly(v.tmp2, 32, 32, 255, 100, 255, lines, filledPolys)
'Balls
visible objs = []
ballCount = 0
objs[ballCount] = Object(rnd(0,width()), 0, 16)
ballCount = ballCount + 1
visible remove = false'temp - for testing
############ to calculate FPS ##########################'added by kevin
visible framecount,lasttime = 999,fps,frametime = 0,starttime = 0,endtime = 0
##########################################################
'-----------
' Main Loop
'-----------
while not keydown(KEY_ESCAPE, true)
'added by kevin
### for FPS calc #########
framecount = framecount + 1
starttime = clock()
###########################
if remove = 0
txt = "false"
else
txt = "true"
endif
'end of added code
' Clear screen
set color 0, 0, 0; cls
' Draw grid
set color 64, 64, 64
for gx = 0 to 640 step 64 draw line gx, 0, gx, 480
for gy = 0 to 480 step 64 draw line 0, gy, 640, gy
' Rotate obstacles: + = clockwise, - = counter-clockwise
square.SetAngle(square.Angle() + rad(0.5))
star.SetAngle(star.Angle() + rad(0.25))
cross.SetAngle(cross.Angle() - rad(0.5))
rectangle.SetAngle(rectangle.Angle() - rad(0.25))
rectangle2.SetAngle(rectangle2.Angle() + rad(0.25))
' draw obstacles
foreach polygn in filledPolys polygn.DrawFilled()
' coordinate labels, infobox
set color 255, 255, 255
shapes = [square,star,cross,rectangle,rectangle2,tmp1,tmp2]
for i = 0 to sizeof(shapes)-1
DrawCoordLabel(shapes[i])
next
set caret width()/2+100, height()-50; center "Press ENTER for more balls"
' balls
foreach ball in objs
UpdateObject(ball)
DrawObject(ball)
next
if keydown(KEY_R,true) then remove = (remove+ 1) % 2
' Remove out-of-bounds balls to prevent unnecessary collision checks
if remove = true'added by kevin
i = 0
while i < ballCount
if objs[i].x > 690 or objs[i].x < -50 or objs[i].y > 530
j = i
while j < ballCount - 1
objs[j] = objs[j + 1]
j = j + 1
wend
ballCount = ballCount - 1
else
i = i + 1
endif
wend
endif
i = 0
while i < ballCount - 1
j = i + 1
while j < ballCount
ResolveBallCollision(objs[i], objs[j])
j = j + 1
wend
i = i + 1
wend
'Drop ball
if keydown(KEY_RETURN,true) 'and ballCount < 32
objs[ballCount] = Object(rnd(0,width()), 0, 16)
ballCount = ballCount + 1
endif
'added by kevin
set caret 320,10;set justification center
write "FPS = " + fps;wln
write "remove balls = " + txt;wln
write "ballCount is " + ballCount + " / objs Table size is " + sizeof(objs);wln
'end
redraw
fwait 60
####### FPS calc ############################
endtime = clock()
frametime = frametime + endtime - starttime
if frametime > 1000 # 1 second
fps = framecount
framecount = 0
frametime = 0
endif
################################################
wend
'------------
' Functions
'------------
function Object(x, y, r)
return [x: x, y: y, r: r, rsqr: r*r, dx: 0, dy: 0, pdx: 0, pdy: 0]
endfunc
' Draw ball
function DrawObject(obj)
set color 255, 255, 0
draw ellipse obj.x, obj.y, obj.r, obj.r, true
endfunc
' Update ball
function UpdateObject(obj)
obj.dy = obj.dy + 0.1
if obj.dy > 6 then obj.dy = 6
' Update position
obj.x = obj.x + obj.dx
obj.y = obj.y + obj.dy
' Collision detection
PushOut(obj, lines)
endfunc
' ResolveBallCollision
function ResolveBallCollision(b1, b2)
dx = b2.x - b1.x; dy = b2.y - b1.y
distSq = dx*dx + dy*dy
minDist = b1.r + b2.r
minDistSq = minDist * minDist
' Early exit if no collision or zero distance
if distSq >= minDistSq or distSq = 0 then return
dist = sqr(distSq)
' push apart
overlap = minDist - dist
b1.x = b1.x - overlap; b1.y = b1.y - overlap
b2.x = b2.x + overlap; b2.y = b2.y + overlap
endfunc
' PushOut: collision resolution
function PushOut(obj, lines)
for i = 1 to 4
col = false
foreach ln in lines
dp = max(0, min(ln[6], (obj.x - ln[0])*ln[4] + (obj.y - ln[1])*ln[5]))
px = ln[0] + dp*ln[4]; py = ln[1] + dp*ln[5]
dx = obj.x - px; dy = obj.y - py
d = dx*dx + dy*dy
if d < obj.rsqr
k = 1/sqr(d)
obj.x = px + dx*k*obj.r
obj.y = py + dy*k*obj.r
obj.dx = obj.dx + 0.5 * dx*k
obj.dy = obj.dy + 0.5 * dy*k
col = true
endif
next
if not col break
next
endfunc
' Polygon
function Polygon(points, x, y, r, g, b)
p = [trans: unset, org: [], verts: [], x: x, y: y, a: 0, cx: 0, cy: 0, r: r, g: g, b: b]
pcount = sizeof(points)/2
' Store original vertices
for i = 0 to pcount - 1
p.verts[sizeof(p.verts)] = points[i*2]
p.verts[sizeof(p.verts)] = points[i*2 + 1]
next
' collision lines
n = pcount - 1
for i = 0 to n
j = (i + 1)%pcount
p.org[sizeof(p.org)] = Line(
points[i*2], points[i*2 + 1],
points[j*2], points[j*2 + 1])
next
for i = 0 to pcount - 1
p.cx = p.cx + points[i*2]; p.cy = p.cy + points[i*2 + 1]
next
p.cx = p.cx/pcount; p.cy = p.cy/pcount
p.trans = copy(p.org)
p.AddTo = function(lines)
foreach ln in .trans lines[sizeof(lines)] = ln
endfunc
p.X = function(); return .x ;endfunc
p.Y = function(); return .y ;endfunc
p.Angle = function(); return .a ;endfunc
p.SetTransform = function(x, y, angle)
.x = x; .y = y; .a = angle; .Transform()
endfunc
p.SetPosition = function(x, y)
.x = x; .y = y; .Transform()
endfunc
p.SetAngle = function(angle)
.a = angle; .Transform()
endfunc
p.Transform = function()
RotateLines(.org, .trans, .cx, .cy, .a)
foreach ln in .trans
ln[0] = ln[0] + .x; ln[1] = ln[1] + .y
ln[2] = ln[2] + .x; ln[3] = ln[3] + .y
ln[4] = (ln[2] - ln[0])/ln[6]; ln[5] = (ln[3] - ln[1])/ln[6]
next
endfunc
p.DrawFilled = function()
set color .r, .g, .b
vcount = sizeof(.verts)/2
polyArgs = []
for i = 0 to vcount - 1
vx = .verts[i*2] - .cx; vy = .verts[i*2 + 1] - .cy
' Apply rotation
rx = vx*cos(.a) - vy*sin(.a)
ry = vx*sin(.a) + vy*cos(.a)
polyArgs[sizeof(polyArgs)] = rx + .cx + .x
polyArgs[sizeof(polyArgs)] = ry + .cy + .y
next
draw poly polyArgs, true
endfunc
p.Transform()
return p
function RotateLines(srcLines, dstLines, aroundX, aroundY, angle)
c = cos(angle); s = sin(angle)
for i = 0 to sizeof(srcLines) - 1
srcLn = srcLines[i]; dstLn = dstLines[i]
x = srcLn[0] - aroundX; y = srcLn[1] - aroundY
dstLn[0] = aroundX + x*c - y*s; dstLn[1] = aroundY + y*c + x*s
x = srcLn[2] - aroundX; y = srcLn[3] - aroundY
dstLn[2] = aroundX + x*c - y*s; dstLn[3] = aroundY + y*c + x*s
next
endfunc
endfunc
function Line(x0, y0, x1, y1)
ln = [x0, y0, x1, y1]
dx = ln[2] - ln[0]; dy = ln[3] - ln[1]
ln[6] = sqr(dx*dx + dy*dy)
ln[4] = dx/ln[6]
ln[5] = dy/ln[6]
return ln
endfunc
function MakePoly(verts, x, y, r, g, b, lines, renderList)
p = Polygon(verts, x, y, r, g, b)
p.AddTo(lines)
renderList[sizeof(renderList)] = p
return p
endfunc
function DrawCoordLabel(p)
set caret p.X(), p.Y()
wln "X"
wln (int(p.X())) + "," + (int(p.Y()))
endfunc
Posts: 196
Threads: 15
Joined: Dec 2023
Reputation:
8
Some progress with the issue of the balls moving inside the polygons. I think the issue is with the ResolveBallCollision() function, which seems, in certain circumstances, to be pushing the balls inside the polygons. To demonstrate, if you disable this function, the problem disappears.
I think it may be a little more difficult to find a solution though
|