03-25-2025, 02:35 PM
(03-24-2025, 06:46 PM)Marcus Wrote: Looks promising
I wish I could help you out with these things. But I know absolutely nothing when it comes to physics programming - I just "cheat" and hope no one notices.
Don't worry about physics simulation, it's just for fun ! Honestly, I even like simplicity more than real physics math. I tried to follow the math in this program, but somewhere between the nested loops and physics, my brain blue-screened. I think I accidentally solved a physics equation, summoned a parallel universe, and now my coffee is floating



click the image to zoom -in
Code:
' Physics Simulation: Stacking
set window "boxes", 400, 600
set redraw off
' Constants
constant gravity = 2 ' Gravity acceleration
constant friction = 0.08 ' Friction factor (velocity decay)
constant groundY = 500 ' Ground level (pixels)
constant tolerance = 0.1 ' Tolerance for resting detection
' Color definiion
black = [0,0,0]
white = [255,255,255]
' Box properties
box = []
box.num = 500 'Number of boxes
box.w = 10 'Width of each box
box.h = 10 'Height of each box
' Initialize boxes
for i = 0 to box.num - 1
box[i] = []
box[i].x = rnd(width()/box.w)*13' Random X position
box[i].y = rnd(100) ' Random Y position (above ground)
box[i].vx = rnd(-0.1,0.1) ' Random X velocity
box[i].vy = 0 ' Initial Y velocity
box[i].angle = 0 ' Initial angle (no rotation)
box[i].va = 50 ' Angular velocity
next
' Function to rotate a point around the origin
function rotatePoint(px, py, angle)
result = dim(2)
result[0] = px * cos(angle) - py * sin(angle)
result[1] = px * sin(angle) + py * cos(angle)
return result
endfunc
'-----------
' Main loop
'-----------
while not keydown(KEY_ESCAPE,true)
' Clear the screen
set color black
cls
set color white
' Draw the ground
draw rect 0, groundY, width(), 20
' Update and draw each box
for i = 0 to box.num - 1
' Apply gravity
box[i].vy = box[i].vy + gravity
' Update position
box[i].x = box[i].x + box[i].vx
box[i].y = box[i].y + box[i].vy
' Update rotation
box[i].angle = box[i].angle + box[i].va
' Check for collision with the ground or another box below
resting = false
' Check for resting on the ground
if box[i].y + box.h / 2 >= groundY then
box[i].y = groundY - box.h/2 ' Ensure no overlap with ground
box[i].vy = 0
resting = true
else
' Check for stacking on another box
j = 0
while j < box.num and not resting
if i <> j and abs(box[i].x - box[j].x) <= box.w / 2 + tolerance and
box[i].y + box.h / 2 >= box[j].y - box.h / 2 - tolerance and box[i].y < box[j].y then
' Resting on another box
box[i].y = box[j].y - box.h ' Ensure no overlap with the box below
box[i].vy = 0
resting = true
endif
j = j + 1
wend
endif
' Resolve overlaps iteratively
for k = 0 to box.num - 1
if i <> k then
' Check for horizontal overlap
if abs(box[i].x - box[k].x) <= box.w / 2 + tolerance then
' Check for vertical overlap
if box[i].y + box.h / 2 > box[k].y - box.h / 2 and box[i].y < box[k].y then
box[i].y = box[k].y - box.h ' Adjust position to avoid overlap
box[i].vy = 0
endif
endif
endif
next
' Stabilize rotation when resting
if resting then
snapAngle = round(box[i].angle / (PI / 2)) * (PI / 2) ' Snap to nearest multiple of 90 degrees
box[i].angle = snapAngle
box[i].va = box[i].va * 0.1 ' Reduce angular velocity significantly
' Apply damping to horizontal velocity
box[i].vx = box[i].vx * 0.9
endif
' Collision with walls
if box[i].x - box.w / 2 <= 0 or box[i].x + box.w / 2 >= 800 then
box[i].vx = box[i].vx * -0.5 ' Reverse X velocity with damping
box[i].va = box[i].va * -0.5 ' Reverse angular velocity with damping
endif
' Draw the box
set color white
halfW = box.w / 2
halfH = box.h / 2
' Calculate vertices of the rotated box
points = dim(8)
p = rotatePoint(-halfW, -halfH, box[i].angle)
points[0] = box[i].x + p[0]
points[1] = box[i].y + p[1]
p = rotatePoint(halfW, -halfH, box[i].angle)
points[2] = box[i].x + p[0]
points[3] = box[i].y + p[1]
p = rotatePoint(halfW, halfH, box[i].angle)
points[4] = box[i].x + p[0]
points[5] = box[i].y + p[1]
p = rotatePoint(-halfW, halfH, box[i].angle)
points[6] = box[i].x + p[0]
points[7] = box[i].y + p[1]
draw poly [points[0], points[1], points[2], points[3],
points[4], points[5], points[6], points[7]]
next
' Refresh
fwait 60
redraw
wend