|
Post by tsh73 on Dec 22, 2020 20:13:51 GMT
Now for some magic
take a 1 meter of thread put a weight on one end hold other end in your arm
Run program below
Then you get used to drawn pendilum swinging, release weight in real thread pendilum so they start swing on same time moment.
Now, real (thread) pendilum and drawn (JustBASIC) pendilum swing in sync.
Isn't that nice?
'simple pendilum
nomainwin WindowHeight=720 WindowWidth=720 UpperLeftX=1 UpperLeftY=1 pi=acs(-1)
open "simple pendilum" for graphics_nsb_nf as #gr #gr "trapclose [quit]" #gr "down" '#gr "fill white; flush" #gr "home; posxy cx cy"
DPI=144 'set your own sc = DPI/2.54*100 'scale, dpi -> dpCm -> dpMeter 'this is likely real scale 'now decrease it 'sc =sc /100 '1:100, 1 meter in 1 cm 'sc =sc /1000 '1:1000, 1 meter in 1 mm sc =sc /10 '1:10, 1 meter in 10 cm of screen 'notice sc '567 pixels in 10 cm of screen
'pendilum g=9.8 'Earth 'g=9.8/6 'Moon
L=1 '1 meter, scaled by sc
R=0.0254 'r=1 in R=0.05 'r=5 cm
A=15*pi/180 'amplitude
'pivot x00=cx:y00=40 #gr "place ";x00;" ";y00 x=x00:y=y00+L*sc #gr "goto ";x;" ";y #gr "circle ";R*sc
'equation '1) simple pendulum for small alpha 'small angle, sin a = a (radians) 'got to 'alph(t)=sin(sqr(g/L)*t)
timer 1, [tick] 'minimal possible t0=time$("ms") wait
[tick] t1=time$("ms") dt=(t1-t0)/1000 'so how much time passed? a=A*sin(sqr(g/L)*dt) #gr "cls" #gr "place ";x00;" ";y00 x=x00+L*sc*sin(a):y=y00+L*sc*cos(a) #gr "goto ";x;" ";y 'print dt, a, x, y #gr "circle ";R*sc
wait
[quit] timer 0 close #gr end
|
|
|
Post by B+ on Dec 23, 2020 17:24:36 GMT
|
|
|
Post by B+ on Dec 23, 2020 18:52:48 GMT
Ah here it is with a little mod! ' ref: https://www.qb64.org/forum/index.php?topic=3056.msg123288#msg123288 ' by FellippeHeitor ported to JB and modified by bplus 2020-12-23
Global Xmax, Ymax, Pi, maxPendulum Xmax = 1100 : Ymax = 600 : Pi = acs(-1) : maxPendulum = 15
'SCREEN _NEWIMAGE(1000, 600, 32) 'CONST maxPendulum = 15 'DIM g, i AS INTEGER DIM Theta(maxPendulum), Accel(maxPendulum), Speed(maxPendulum) DIM Length(maxPendulum), Mass(maxPendulum) 'DIM px, py, bx, by g = 9.81 FOR i = 0 TO maxPendulum Theta(i) = Pi / 1.5 Speed(i) = 0 Length(i) = 100 + i * 30 Mass(i) = 1 - i * .01 NEXT
'px = _WIDTH / 2 px = Xmax /2 py = 0
'DO UNTIL _SCREENEXISTS: _LIMIT 1: LOOP '_TITLE "Pendula"
nomainwin
WindowWidth = Xmax + 8 WindowHeight = Ymax + 32 UpperLeftX = (1200 - Xmax) / 2 'or delete if XMAX is 1200 or above UpperLeftY = (700 - Ymax) / 2 'or delete if YMAX is 700 or above
open "Pendula by FellippeHeitor port to JB and modified by bplus" for graphics_nsb_nf as #gr #gr "setfocus" #gr "trapclose Quit" #gr "when leftButtonUp lButtonUp" '#gr "when characterInput charIn" #gr "down" #gr "fill black" 'DO #gr "color white" while 1 scan 'CLS #gr "fill black" 'WHILE _MOUSEINPUT: WEND ' see mouse handler event FOR i = 1 TO maxPendulum 'IF _MOUSEBUTTON(1) THEN 'check mouse click 'theta(i) = map(_MOUSEX, 0, _WIDTH - 1, 4.7, 1.57) 'speed(i) = 0 'ELSE Accel(i) = Mass(i) * g * SIN(Theta(i)) / 100 Speed(i) = Speed(i) + Accel(i) / 100 Theta(i) = Theta(i) + Speed(i) 'END IF bx = px + Length(i) * SIN(Theta(i)) by = py - Length(i) * COS(Theta(i)) 'LINE (px, py)-(bx, by), c(i) #gr "line ";px;" ";py;" ";bx;" ";by 'CircleFill bx, by, map(i, 0, maxPendulum, 20, 40), c(i) if i mod 2 then #gr "backcolor red" else #gr "backcolor darkgreen" #gr "place ";bx;" ";by;"; circlefilled ";20 #gr "place ";bx-4;" ";by+4;";|";mid$("Merry Christmas", i, 1) NEXT '_DISPLAY 'gotta live with the blinking '_LIMIT 60 call Pause 40 'any less Pause is blinky, if you get too much blick raise the Pause number 'LOOP wend wait
FUNCTION Map (value, minRange, maxRange, newMinRange, newMaxRange) Map = ((value - minRange) / (maxRange - minRange)) * (newMaxRange - newMinRange) + newMinRange END FUNCTION
sub lButtonUp H$, mx, my 'must have handle and mouse x,y FOR i = 1 to maxPendulum 'theta(i) = map(_MOUSEX, 0, _WIDTH - 1, 4.7, 1.57) Theta(i) = Map(mx, 0, Xmax, 4.7, 1.57) Speed(i) = 0 next end sub
sub Quit H$ close #gr '<=== this needs Global H$ = "gr" < blah never works right! end end sub
sub Pause mil 'tsh version has scan built-in t0 = time$("ms") while time$("ms") < t0 + mil : scan : wend end sub
Hmm... takes a little longer to set up patterns because if try to speed Pauses the blinking gets too annoying. Attachments:
|
|
code
Member in Training
Posts: 74
|
Post by code on Dec 23, 2020 20:04:10 GMT
Pretty cool both... thx for sharing !
|
|
|
Post by tsh73 on Dec 23, 2020 20:34:00 GMT
Wow wow!
Such a nice real physics (first link video)! Such a nice animation! (program)
As for blinking probably sprites could help, one has to try. (of course I set pause to minimum :))
Now I look inside - it has real differential equation. Me thinks it will look more "real" if initial amplitude will be smaller. Like
Theta(i) = Pi / 1.1 instead of
Theta(i) = Pi / 1.5
It really looks rotating in 3d, and green disks looks transparent glass with all that white threads shining through.
But it looks like there is some corners cut in a math. Pendulum frequency should not depend on a mass - but here masses are different, and if I make mass the same, all balls go with same frequency. (probably masses compensate for equation on angle do not accounting for thread length)
Looks really real anyway
Btw if you wait long enough, red balls separate and say
- perfectly recognizable!
Btw2 increasing "g" value makes it runs faster. Like, g = g*10
Btw3 (sorry)
#gr "discard" in the loop prevents graphic memory build-up, thus making it faster
|
|
|
Post by Rod on Dec 23, 2020 20:43:23 GMT
Yes super cool, and thanks to Anatoly for the inspiration. You both make this forum really interesting and worthwhile.
|
|
|
Post by B+ on Dec 24, 2020 4:47:15 GMT
Thanks Rod and tsh73 for 2 of the 3 BTW's, a higher g sounds good and I always forget about #gr "discard".
|
|