Board Logo
« Flying marble »

Welcome Guest. Please Login or Register.
Jan 16th, 2018, 3:40pm


Conforums Terms of Service | Membership Rules | Home | Search | Recent Posts | Notification | Format Your Message | Installation FAQ

Please use the forums Search feature before asking.
Please post code using the code box described in Format Your Messages.
This will keep indentation, separate it better form the message and prevent gibberish.
If the code is too long for one post or additional files are needed, upload a ZIP archive to the Just BASIC Files Archive Site.

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Flying marble  (Read 178 times)
tsh73
JB-Supporter


member is offline

Avatar




PM

Gender: Male
Posts: 3635
xx Flying marble
« Thread started on: Nov 27th, 2017, 03:18am »

Looks pretty natural to me ;)
(as for inspiration - I've seen it on some Spectrum demo on Youtube)

It's switching between "free fall" and "rotational movement"
constants are fiddled with so it looks seamless.
(may make cleaned-up version later - too much cludges at the moment)

But it works!
Code:
'flying marble
'by tsh73 Nov 2017
'based on
'   "Rotating lever" code
'   http://justbasic.conforums.com/index.cgi?board=novice&action=display&num=1509449023
'(and it's full of cludges)
gosub [getSlack]
    desiredWidth = 900
    desiredHeight = 750
    WindowWidth = desiredWidth + slackX
    WindowHeight = desiredHeight + slackY

nomainwin
UpperLeftX = 1
UpperLeftY = 1

open "Flying marble" for graphics_nsb_nf as #gr
#gr "trapclose [quit]"
#gr "down"

pi = acs(-1)
g = 9.8

cx=250:cy=550
fx=600
'---------------------------------------
'      A_______^___________B           freeFalling
'---------------------------------------
'===== data goes here ==========
lA=1
lB=0'1.5
mA=1
mB=0'1.5
'===============================

'moment
angle0 = pi
angle = angle0
momentA=0-mA*cos(angle)*lA*g
momentB=mB*cos(angle)*lB*g       'clockwise is positive
moment = momentA+momentB

Inertcia = mA*lA^2+mB*lB^2
AngAccel=moment/Inertcia
angVel0=9
angVel=angVel0
'actually right only for initial moment. But we don't care much
'now, for B
'linAccelB=AngAccel*lB

'count in meters, draw in pixels
scale = 100 'pixel per meter
r=scale*lA+mA*10

delay = 16      'ms
dt = delay/1000 'sec


x = fx/scale
y = 0
vy=0
minY=2.5
t0=time$("ms")

state=0    '0..5
numStates=6
'transitions from state to state
dim rotOut(numStates)    'angle where rotation ends
dim rotSign(numStates)  'rotation direction, 1 clockwise, -1 counterCW
dim angle0(numStates)   'where rotation starts
delta = .13
rotOut(0)=2*pi-delta
rotOut(2)=pi-delta
rotOut(4)=(2+.355)*pi
rotSign(0)=1
rotSign(2)=-1
rotSign(4)=1
dim rotCx(numStates), rotCy(numStates)    'rotational centers
rotCx(0)=cx: rotCy(0)=cy
rotCx(2)=cx+2*r: rotCy(2)=cy
rotCx(4)=cx+4*r: rotCy(4)=cy
angle0(2)=2*pi
angle0(4)=pi
angle0(0)=pi-(rotOut(4)-2*pi)
dim yOut(numStates)    'y where rotation starts
yOut(1)=0
yOut(3)=0
yOut(5)=0-sin(rotOut(4))

call arc cx, cy, r, 0, 2*pi-angle0(0)
call arc cx+2*r, cy, r, 0, pi
call arc cx+4*r, cy, r, 0-(rotOut(4)-2*pi),pi
#gr "flush"


fall=state mod 2
gosub [drawFallingBall]
gosub [drawLever]

timer delay, [nxt]

[nxt]
    #gr "color white"
    gosub [drawFallingBall]
    gosub [drawLever]
    if fall=0 then
[again]
        momentA=0-mA*cos(angle)*lA*g
        momentB=mB*cos(angle)*lB*g       'clockwise is positive
        moment = momentA+momentB

        Inertcia = mA*lA^2+mB*lB^2
        AngAccel=moment/Inertcia

        angVel=angVel+dt*AngAccel
        anglePrev = angle
        angle=angle+dt*angVel
        'reset to initials so it never flew off
        if state=0 and angle > angle0 and  angle0 >anglePrev then
              angle=angle0
              angVel=angVel0
              'print "reset"
              goto [again]
        end if
        'print time$("ms"),angle, anglePrev

        if angle*rotSign(state)>rotOut(state)*rotSign(state) then
            'now, fix the angle so it flew right way
            angle=rotOut(state)
            'next state
            state=(state+1) mod numStates
                'print " state="; state
            fall=state mod 2 'switch to free fall
            y=lA*sin(angle)
                if state = 5 then y = 0-y
            x=lA*cos(angle)
            vy=0-angVel*lA*cos(angle)
            vx=0-angVel*lA*sin(angle)
            'print x, y, vx, vy
                #gr "color black"
            gosub [drawFallingBall]
            'timer 0
            ' #gr "flush"
            'wait
        end if
    else
        vy=vy+dt*g
        y=y+dt*vy
        x=x+dt*vx
        'print time$("ms"),x,y
'if state = 5 then print "(5)",y
        'if  (state <> 5) and (y >yOut(state)) then
        if  (y >yOut(state)) then
            'next state
            state=(state+1) mod numStates
            'print " state="; state
            fall=state mod 2 'switch to free fall
            cx=rotCx(state)
            angVel=sqr(vy^2+vx^2)/lA*rotSign(state)
            'print angVel
            'angVel=-9
            angle=angle0(state)
        end if
    end if

    #gr "color black"
    if fall=0 then
        gosub [drawLever]
    else
        gosub [drawFallingBall]
    end if


    'if abs(angle-pi)>pi/6 then  'stops after 30 degrees slant
    '    timer 0
    'end if

    if y >minY then
        'timer 0
        vy=0-vy 'absolutely elastic. Actiually it gradually slows down...
        y=minY    'sometimes it goes under
    end if
wait

[drawFallingBall]
    #gr "place ";cx+x*scale;" ";cy+y*scale
    'if fall=1 then print "place ";cx+x*scale;" ";cy+y*scale
    #gr "circle ";mA*9
return

[drawLever]
    '#gr "place ";cx;" ";cy
    '#gr "circle 3"

    otherX=lA*cos(angle)
    otherY=0-lA*sin(angle)
    '#gr "line ";cx;" ";cy;" ";cx+otherX*scale;" ";cy+otherY*scale
    #gr "place ";cx+otherX*scale;" ";cy+otherY*scale
    #gr "circle ";mA*9

    'otherX=lB*cos(angle+pi)
    'otherY=0-lB*sin(angle+pi)
    '#gr "line ";cx;" ";cy;" ";cx+otherX*scale;" ";cy+otherY*scale
    '#gr "circle ";mB*10

return
'========================================

[quit]
    timer 0
    close #gr
end

[getSlack]
    WindowWidth=200:WindowHeight=200
    open "" for graphics_nsb as #t:#t,"home;posxy x y":close#t
    slackX=WindowWidth-2*x:slackY=WindowHeight-2*y
return

sub arc cx, cy, r, a0, a1  'from angle to angle
'print cx, cy, r, a0, a1
    da = 3.14/r
    x=cx+r*cos(a0)
    y=cy+r*sin(a0)
    #gr "place ";x;" ";y
    for a = a0 to a1 step da
        x=cx+r*cos(a)
        y=cy+r*sin(a)
        #gr "goto ";x;" ";y
        'print a, x, y
    next
'    end
end sub
 
User IP Logged

Q: "And if I took your codes and compile them, and sell them for a profit"?
A: Go ahead. I had my share of good then I coded it for fun, if you can make better use of it - please do.
(enjoying JB 1.01 on WinXP, netbook and desktop)
bplus
Senior Member
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 1255
xx Re: Flying marble
« Reply #1 on: Nov 27th, 2017, 11:05am »

Hey cute! smiley
User IP Logged

B+
Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

Conforums Terms of Service | Membership Rules | Home | Search | Recent Posts | Notification | Format Your Message | Installation FAQ

Donate $6.99 for 50,000 Ad-Free Pageviews!

| |

This forum powered for FREE by Conforums ©
Sign up for your own Free Message Board today!
Terms of Service | Privacy Policy | Conforums Support | Parental Controls