Did someone ask for a pendulum simulation? The physics behind it isn't too bad.
Probably could have been done with gdip.ahk but I didn't want dependencies on external libraries if it's going on Rosetta Code. (so you can just copy the code and run it)
Code: Select all
angle := 3.14159 / 2.5 ;Starting angle in radians
velocity := 0 ;Initial angular velocity in radians/second
dt := 0.01 ;How often to update the simulation in seconds
gravity := -9.81 ;Acceleration due to gravity
lineColor := 0xffffff ;Line and ball outline color
ballColor := 0xee00ff ;Ball color
backColor := 0x000000 ;Background color
radius := 12 ;Ball radius in pixels
timescale := 5 ;Simulation speed multiplier (1 = realtime)
width := 500 ;Window width in pixels
height := 500 ;Window height in pixels
length := floor(0.4*(width < height ? width : height)) ;Line length in pixels
;Set up gui and memory bitmap
Gui, +hwndDrawSurface
hdc := DllCall("GetDC", "ptr", DrawSurface)
mdc := DllCall("CreateCompatibleDC", "ptr", hdc)
hbm := DllCall("CreateCompatibleBitmap", "ptr", hdc, "int", width, "int", height)
;Set up drawing resources
BallBrush := DllCall("CreateSolidBrush", "uint", ballColor)
LinePen := DllCall("CreatePen", "int", 0, "int", 2, "uint", lineColor)
BackBrush := DllCall("CreateSolidBrush", "uint", backColor)
;Get the default objects for cleanup later
defaultBitmap := DllCall("SelectObject", "ptr", mdc, "ptr", hbm)
defaultBrush := DllCall("SelectObject", "ptr", mdc, "ptr", BallBrush)
defaultPen := DllCall("SelectObject", "ptr", mdc, "ptr", LinePen)
;Show window and create a timer to update and redraw the pendulum
Gui, Show, w%width% h%height%
SetTimer, UpdatePendulum, % 1000*dt
dt *= timescale
return
UpdatePendulum:
;Update physics
acceleration := gravity / length * sin(angle)
velocity += acceleration * dt
angle += velocity * dt
ballx := width//2 + sin(angle)*length
bally := height//2 + cos(angle)*length
;Draw line first, then the ball on top
DllCall("MoveToEx", "ptr", mdc, "int", width//2, "int", height//2, "ptr", 0)
DllCall("LineTo", "ptr", mdc, "int", ballx, "int", bally)
DllCall("Ellipse", "ptr", mdc, "int", ballx-radius, "int", bally-radius, "int", ballx+radius, "int", bally+radius)
;Draw the memory bitmap onto the window
DllCall("BitBlt", "ptr", hdc, "int", 0, "int", 0, "int", width, "int", height, "ptr", mdc, "int", 0, "int", 0, "uint", 0xCC0020)
;Clear the memory bitmap with the back color
DllCall("SelectObject", "ptr", mdc, "ptr", BackBrush)
DllCall("Rectangle", "ptr", mdc, "int", 0, "int", 0, "int", width, "int", height)
;Put the ball brush back
DllCall("SelectObject", "ptr", mdc, "ptr", BallBrush)
return
GuiClose:
;Cleanup
DllCall("SelectObject", "ptr", mdc, "ptr", defaultBitmap)
DllCall("SelectObject", "ptr", mdc, "ptr", defaultBrush)
DllCall("SelectObject", "ptr", mdc, "ptr", defaultPen)
DllCall("DeleteObject", "ptr", hbm)
DllCall("DeleteObject", "ptr", BallBrush)
DllCall("DeleteObject", "ptr", LinePen)
DllCall("DeleteObject", "ptr", BackBrush)
DllCall("ReleaseDC", "ptr", DrawSurface, "ptr", hdc)
DllCall("DeleteDC", "ptr", mdc)
ExitApp
return