Thread Rating:
  • 1 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Rectangle (simple physics)
#3
(03-24-2025, 06:46 PM)Marcus Wrote: Looks promising Smile

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  Big Grin Big Grin Big Grin

           
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
Reply


Messages In This Thread
Rectangle (simple physics) - by 1micha.elok - 03-23-2025, 10:16 AM
RE: Rectangle (simple physics) - by Marcus - 03-24-2025, 06:46 PM
RE: Rectangle (simple physics) - by 1micha.elok - 03-25-2025, 02:35 PM
RE: Rectangle (simple physics) - by johnno56 - 03-25-2025, 07:26 PM

Forum Jump:


Users browsing this thread: 1 Guest(s)