1 A Core Course on Modeling Enter: ACCEL basics running a script Time in ACCEL the { … } operator...

Post on 27-Dec-2015

214 views 0 download

Transcript of 1 A Core Course on Modeling Enter: ACCEL basics running a script Time in ACCEL the { … } operator...

1

A Core Course on Modeling

• Enter: ACCEL

• basics

• running a script

• Time in ACCEL

• the { … } operator

• examples

Week 3 – Time for Change

2

A Core Course on Modeling

ACCEL

Week 3 – Time for Change

• intro and PR

• line-by-line, navigate a script

• assistance

• enter a script as text

• numerical analysis

• optimization

• larger view on simulation output

3

A Core Course on Modeling

ACCEL

Week 3 – Time for Change

p=5

q=slider(10,0,20)

r=p+q

Example of a script:

Every line introduces a quantity

Quantities can be constants (p)

Quantities can be functions r = f(p,q)

Quantities can be user-entered (q)

paste into IO/edit box

click ‘run’

4

A Core Course on Modeling

ACCEL

Week 3 – Time for Change

If something STRANGE happens:• don't panic• goto IO/edit• ctrl-A (select all)• ctrl-C (copy all)• ctrl-V into text editor to save

your script • reload ACCEL• goto IO/edit• ctrl-V to load script into ACCEL• retry image: http://partlycloudyjuly.wordpress.com/2011/02/25/look-both-waysimage: http://partlycloudyjuly.wordpress.com/2011/02/25/look-both-ways//

5

A Core Course on Modeling

ACCEL

Week 3 – Time for Change

s=slider(10,0,20)

// this is a slider

r=p+q

// this is an expression

p=5

// this is a constant

q=s+t

// this is an expression

t=pow(s,3)

// this is a standard

// function

Example of a script with comment:

to see values:

click ‘show/hide values’

to see dependencies:

click on ‘pauze’, next click on any quantity

6

A Core Course on Modeling

ACCEL

Week 3 – Time for Change

s=slider(10,0,100)

z=plot([gr1,gr2])

gr1=[str,[s]]

gr2=[str,[s % 10]]

str='x:{mode:intp},y:{mode:shift,ref:1}'

Example of a script with visual output:

plot([graph1,graph2,…, graphn]) plots n graphs

graphi = [format,data]

format = string, e.g. ' x:{mode:intp},y:{mode:shift,ref:1}'

data = one or more quantities Black Magic for now …

Black Magic for now …

7

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

Remember recursive functions:

Qcurrent = f (Qprev, Pprev)

Simplest example:

timecurrent = timeprev + 1

8

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

p=t

t=t{1}+1

ACCEL uses {1} to access previous value

ACCEL uses {n} to access n-th previous value, n>0

ACCEL initializes after modification in script

Start conditions: ACCEL initializes all quantities to 0, unless you use { … |(value in case historic value is lacking)}

9

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

p=k

k=if(t>0,k{1}+5,0)

t=t{1}+1

ACCEL can be forced to re-initialize after nr steps:

10

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

z=descartes([gr1,gr2])

gr1=[str1,[s]]

gr2=[str2,[50+s-s{1}]]

s=50+25*sin(t/10)

z=descartes([gr1,gr2])

gr1=[locations:[x:[mode:'intp'],y:[mode:'shift',value:s]],edges:[thickness:2,col_r:255]]

gr2=[locations:[x:[mode:'intp'],y:[mode:'shift',value:50+s-s{1}]],edges:[thickness:2,col_b:255]]

t=t{1}+1

Implement first derivative image: http://www.treklens.com/gallery/photo593123.htmimage: http://www.treklens.com/gallery/photo593123.htm

11

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

z=descartes([gr1,gr2])

gr1=[locations:[x:[mode:'intp'],y:[mode:'shift',value:50+10*rate]],edges:[thickness:2,col_r:if(rate>0,0,255),col_g:if(rate>0,255,0)]]

gr2=[locations:[x:[mode:'intp'],y:[mode:'shift',value:50+supply]],edges:[thickness:2,col_b:255]]

rate=slider(0,-0.5,0.5)

supply=supply{1}+rate

Implement integral image: http://www.themarketingexpert.net/2011/12/leaky-bucket.htmlimage: http://www.themarketingexpert.net/2011/12/leaky-bucket.html

12

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

z=descartes([gr2,gr1])

gr1=[locations:[x:[mode:'intp'],y:[mode:'shift',value:s]],edges:[thickness:2,col_r:255]]

gr2=[locations:[x:[mode:'intp'],y:[mode:'shift',value:ds]],edges:[thickness:2,col_b:255]]

s=slider(50,0,100)

ds=(1-damp)*s+damp*ds{1}

damp=slider(0.5,0.01,0.99)

Implement damping image: http://www.acecontrols.co.uk/product-rangeimage: http://www.acecontrols.co.uk/product-range

13

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

z=descartes([gr1,gr2])

gr1=[locations:[x:[mode:'intp'],y:[mode:'shift',value:s]],edges:[thickness:2,col_r:255]]

gr2=[locations:[x:[mode:'intp'],y:[mode:'shift',value:s{delay}]],edges:[thickness:2,col_b:255]]

s=slider(50,0,100)

delay=slider(1,1,100)

Implement delayimage: http://www.rainbowresource.com/prodlist.php?subject=20&category=8753image: http://www.rainbowresource.com/prodlist.php?subject=20&category=8753

t t i iK(t) K(t) KKii

u(t) u(t) uuii

u’(t) u’(t) (u(t+ (u(t+)-u(t))/)-u(t))/ = (u = (ui+1i+1-u-uii)/)/

v’(t) v’(t) (v(t+(v(t+)-v(t))/)-v(t))/ = (v = (vi+1i+1-v-vii)/)/So uSo ui+1i+1= u= uii++vvi i

vvi+1i+1= v= vii++aai i = =

= v= vii++KKii/m =/m =

= v= vii++ C(u C(urestrest-u-uii) /m) /m

Recursive function Recursive function QQcurrcurr=F(Q=F(Qprevprev,P,Pprevprev))::uucurrcurr=F=F11(u(uprevprev,v,vprevprev)=u)=uprevprev++vvprevprev

vvcurrcurr=F=F22(v(vprevprev,u,uprevprev)=)= =v=vprevprev++ C(u C(urestrest-u-uprevprev) /m,) /m,with suitable uwith suitable u00 and v and v0 0

Equal intervalsEqual intervals: a mass-spring system: a mass-spring systemwith damping. with damping. From physics, we know K=ma where From physics, we know K=ma where K=C(uK=C(urestrest-u) and a=u’’. -u) and a=u’’. Write v=u’, then a=v’.Write v=u’, then a=v’.Here, K=K(t), u=u(t). Let us approximate by Here, K=K(t), u=u(t). Let us approximate by sampling. For sampling. For 0:0:

outout

14

A Core Course on ModelingWeek 3 – Time for Change

time in ACCEL

t t i iK(t) K(t) KKii

u(t) u(t) uuii

u’(t) u’(t) (u(t+ (u(t+)-u(t))/)-u(t))/ = (u = (ui+1i+1-u-uii)/)/

v’(t) v’(t) (v(t+(v(t+)-v(t))/)-v(t))/ = (v = (vi+1i+1-v-vii)/)/So uSo ui+1i+1= u= uii++vvi i

vvi+1i+1= v= vii++aai i = =

= v= vii++KKii/m =/m =

= v= vii++ C(u C(urestrest-u-uii) /m) /m

Recursive function Recursive function QQcurrcurr=F(Q=F(Qprevprev,P,Pprevprev))::uucurrcurr=F=F11(u(uprevprev,v,vprevprev)=u)=uprevprev++vvprevprev

vvcurrcurr=F=F22(v(vprevprev,u,uprevprev)=)= =v=vprevprev++ C(u C(urestrest-u-uprevprev) /m,) /m,with suitable uwith suitable u00 and v and v0 0

Equal intervalsEqual intervals: a mass-spring system: a mass-spring systemwith damping.with damping.From physics, we know K=ma where From physics, we know K=ma where K=C(uK=C(urestrest-u) and a=u’’. -u) and a=u’’. Write v=u’, then a=v’.Write v=u’, then a=v’.Here, K=K(t), u=u(t). Let us approximate by Here, K=K(t), u=u(t). Let us approximate by sampling. For sampling. For 0:0:

--vv

( -( -vvprevprev))

( -( -vvii))

outout

15

A Core Course on ModelingWeek 3 – Time for Change

time in ACCEL

Equal intervalsEqual intervals

WARNING:WARNING: 0 is not the same as '0 is not the same as '=small'. =small'.

The substitutions for u’(t) and v’(t) are approximations only. The substitutions for u’(t) and v’(t) are approximations only.

As we will see in a later example, aliasing errors are worse when the As we will see in a later example, aliasing errors are worse when the sampled signal changes rapidly, compared to the sampling rate. sampled signal changes rapidly, compared to the sampling rate.

Concrete: unless Concrete: unless is much smaller than the period of the oscillation is much smaller than the period of the oscillation (=(=m/C), the approximations are bad – with the risk of instability.m/C), the approximations are bad – with the risk of instability.

16

A Core Course on ModelingWeek 3 – Time for Change

time in ACCEL

outout

Infinitesimal intervalsInfinitesimal intervals

the mass-spring system with damping revisited. the mass-spring system with damping revisited. From physics, we know K=ma where K=C(uFrom physics, we know K=ma where K=C(urestrest-u) and a=u’’. -u) and a=u’’.

For some purposes the numerical solution (sampling) is not For some purposes the numerical solution (sampling) is not acceptable.acceptable.

Interested in outcome? Interested in outcome? use better numerical methods use better numerical methodsInterested in insight? Interested in insight? try to use symbolic methods, i.e.: analysing try to use symbolic methods, i.e.: analysing differential equationsdifferential equationsOnly possible in very few special casesOnly possible in very few special casesIn particular: linear (sets of) DE’s.In particular: linear (sets of) DE’s.

17

A Core Course on ModelingWeek 3 – Time for Change

time in ACCEL

Infinitesimal intervalsInfinitesimal intervals

the mass-spring system with damping revisited. the mass-spring system with damping revisited. From physics, we know K=ma where K=C(uFrom physics, we know K=ma where K=C(urestrest-u) and a=u’’. -u) and a=u’’.

Here, K=K(t), u=u(t). Let us try a solution of the formHere, K=K(t), u=u(t). Let us try a solution of the form

u=uu=urestrest+A sin(t/T) +A sin(t/T) u’’= -ATu’’= -AT-2-2sin(t/T)sin(t/T)

Substitute back:Substitute back:-mAT-mAT-2-2sin(t/T)=C(usin(t/T)=C(urestrest-u-urestrest-Asin(t/T) ),-Asin(t/T) ),mTmT-2-2=C, or T= =C, or T= m/C ( =:Tm/C ( =:T00))

outout

18

A Core Course on ModelingWeek 3 – Time for Change

time in ACCEL

Infinitesimal intervalsInfinitesimal intervals

the mass-spring system with damping revisited. the mass-spring system with damping revisited. From physics, we know K=ma where K=C(uFrom physics, we know K=ma where K=C(urestrest-u) and a=u’’. -u) and a=u’’.

Here, K=K(t), u=u(t). Here, K=K(t), u=u(t). try u=utry u=urestrest+Ae+Aett,,then C+then C++m+m22=0, or=0, or1,21,2=(- =(- ((22-4mC))/2m-4mC))/2mLet Let 00==(4mC). (4mC). For For = = 00 critical damping; critical damping;for for < < 00 oscillations; T=T oscillations; T=T00//(1- ((1- ( / /00))22))for for > > 00 super critical damping super critical damping(further details: lectures ‘dynamical systems’)(further details: lectures ‘dynamical systems’)

outout

--vv

By substituting u = AeBy substituting u = Aett into into

C(uC(urestrest-u)--u)-u’=mu’’ and usingu’=mu’’ and using

u’=Au’=Aeett; u’’=A; u’’=A22eett..

C(uC(urestrest-u-urestrest-Ae-Aett)- )- AAeett=mA=mA22eett

Must hold for any t, so indeedMust hold for any t, so indeed

C + C + + m + m22=0=0

19

A Core Course on ModelingWeek 3 – Time for Change

time in ACCEL

20

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

c=slider(5,1,20.0)delta=slider(0.1,0.001,0.2)m=slider(5,1,10)mu=slider(0,0,1.5)reset=button()z=descartes([gr1,gr2])gr1=[locations:[x:[mode:'intp'],y:[mode:'shift',value:40+10*u]],edges:[thickness:2,col_r:255]]

gr2=[locations:[x:[mode:'intp'],y:[mode:'shift',value:45+10*u_exact]],edges:[thickness:2,col_g:255]]

F=-c*u{1}-mu*v{1}a=F/mdiscr=mu*mu-4*m*clambda_img=cond(discr>0,0,sqrt(-discr)/(2*m))lambda_real=cond(discr>0,(-mu+sqrt(discr))/(2*m),-mu/(2*m))u_exact=cond(discr>0,exp(lambda_real*t),exp(lambda_real*t)*cos(lambda_img*t))

t=if(reset,0,t{1}+delta)u=if(reset,1,u{1}+delta*v)v=if(reset,0,v{1}+delta*a)

A mass-spring systemA mass-spring system

user inputuser input

graphicsgraphics

force and force and accelerationacceleration

exactexactsolutionsolution

recursive functionsrecursive functions

21

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

A cannon shot simulation

http://thehumanmarvels.com/1634/zazel-the-human-cannonball/talentshttp://thehumanmarvels.com/1634/zazel-the-human-cannonball/talents

x

y

y(t) = vy t + gt2/2

x(t) = vx t

y(t) = 0 , so t = 2 vy / g

Then x = 2 vx vy / g

2 (cos sin ) / g

= sin 2 /g

Maximize x: = 45o

But what in case of damping?

22

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

airDamp=slider(0.005,0,0.03)dt=slider(0.1,0.02,40.0)phi=slider(0,0,1.5)plotBall=descartes([[locations:[fill:'interior',x:r.x,y:r.y,rad:2.5]]])px=r.xg=-0.003groundDamp=0.02v=0.55boom=(r{1}.vx<0.000001)newVx=r{1}.vx*(1-velDamp*dt)newVy=r{1}.vy+(g-velDamp*r{1}.vy)*dtnewX=min(r{1}.x+dt*r{1}.vx,100)newY=max(r{1}.y+dt*r{1}.vy,0)r=if(boom,startR,simR)simR=['x':newX,'y':newY,'vx':newVx,'vy':newVy]startR=['x':0,'y':20,'vx':v*cos(phi),'vy':v*sin(phi)]velDamp=if(r{1}.y>0,airDamp,groundDamp)

A cannon shot simulation

23

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

A combat simulation

Lanchester's Law:

e1 : nr troops of army 1

e2: nr troops of army 2

1: relative strength of 1

2 : relative strength of 2

then

de1/dt = - 2 e2

de2/dt = - 1e1

Given e1(t=0)=e10, e2(t=0)=e20,

who wins?

http://www.napolun.com/mirror/napoleonistyka.atspace.com/default.htmhttp://www.napolun.com/mirror/napoleonistyka.atspace.com/default.htm

24

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

A combat simulation

p=check(true)e1=if(p,e1_0,max(0,e1{1}-lambda_2*e2{1}))e2=if(p,e2_0,max(0,e2{1}-lambda_1*e1{1}))lambda_1=slider(0.01,0,0.02)lambda_2=slider(0.01,0,0.02)e1_0=slider(100,0,500)e2_0=slider(100,0,500)res=descartes([graph1,graph2])graph1=[locations:[x:[mode:'intp'],y:[mode:'shift',value:e1/5],rad:1,fcol_r:255,fill:'interior']]graph2=[locations:[x:[mode:'intp'],y:[mode:'shift',value:e2/5],rad:1,fcol_g:255,fill:'interior']]

25

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

A predator - prey simulation

http://q-rai.deviantart.com/http://q-rai.deviantart.com/

Lotka – Volterra model:

br = birth rate of rabit (autonomous)

bf = birth rate of fox, feeding on rabit

dr = rabits killed by fox

df = death rate of fox (autonomous)

r / t = r (br – dr f)

f / t = f (bf r – df )

26

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

bf=slider(1.5,0,5)br=slider(3,0,5)df=slider(1,0,5)dr=slider(1,0,5)dt=slider(0.15,0.01,0.2)reset=button()

p=descartes([gboth,gfox,grab])gboth=[locations:[fill:'interior',nrLocations:50,rad:2.5,fcol_r:50,x:[mode:'shift',value:10+3*f],y:[mode:'shift',value:10+3*r]]]

gfox=[locations:[y:[mode:'intp'],x:[mode:'shift',10+3*f]],edges:[thickness:2,col_r:255]]grab=[locations:[x:[mode:'intp'],y:[mode:'shift',10+3*r]],edges:[thickness:2,col_b:255]]f=if((time<2)||reset,150,max(0.01,f{1}+dt*(bf*f{1}*r{1}-df*f{1})))

r=if((time<2)||reset,150,max(0.01,r{1}+dt*(br*r{1}-dr*f{1}*r{1})))

time=time{1}+1

A predator - prey simulation

user inputuser input

graphicsgraphics

recursive functionsrecursive functions

timetime

27

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

A billiards simulation

http://joyreactor.com/tag/billiardshttp://joyreactor.com/tag/billiards

vr

v'r

vw

v'w

r w= - r =

=:

= (vw-vr , )

; ||||=1

28

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

A billiards simulation

vr

v'r

vw

v'w

r w= - r =

=:

= (vw-vr , )

; ||||=1

Proof: Energy conservation:

vr2+vw

2=(vr+)2+(vw-)2, hence

vr2+vw

2=(vr+)2+(vw-)2, hence

0=(2(vr, )+2)+(-2(vw, )+2), hence

= (vw-vr, ), QED

29

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

A billiards simulation

vr

v'r

vw

v'w

r w= - r =

=:

= (vw-vr , )

; ||||=1

v'r=vr+(vw-vr , )

v'w=vw+(vr-vw , )

Proof: Energy conservation:

vr2+vw

2=(vr+)2+(vw-)2, hence

vr2+vw

2=(vr+)2+(vw-)2, hence

0=(2(vr, )+2)+(-2(vw, )+2), hence

= (vw-vr, ), QED

30

A Core Course on Modeling

time in ACCEL

Week 3 – Time for Change

A billiards simulation

maxX=40minX=-40maxY=25minY=-25halfWay=50// half of the screen; used to correct the queueX and queueY coordinateshelp=check(false)// plot the direction of the queuenBalls=3// nr balls// This is also hard coded in the colors; if the nr balls should change, only the color// arrays have to be updatedrhoBall=slider(1.4,0.6,4)// radius of the ballsmBall=5// mass of the ballstime=time{1}+1rollDamp=0.994// the damping coefficient for the rolling ballscollDamp=0.6// the damping coefficient for colliding ballseThreshold=0.5// the minimum kinetic energy for the balls to stay rollingdT=0.8// to go from physical time to simulation timePR=plot([plotTable,plotShadow,plotBalls,plotHighLight,plotQueue,plotQueue2]) // one graph consisting of three balls. The x and y coordinates are // taken from the 'x'- and 'y'-components of the r-vector that has to be transposed in order to get // the x-s and y-s in two separate vectors. tVec(i,j)=@(r{1},j)-@(r{1},i) // the vector pointing from ball i to ball j, with coefficients x and ycpl=#(i,vSequence(0,nBalls),cplOneBall(i),vAppend) // the couplings matrix containing all info about the relations to ball i, // that is: 'close' to indicate if these two balls are in a collision-state; // if close is true, 'force' is the current reaction force between them.tMat=#(i,vSequence(0,nBalls),tMatOneBall(i),vAppend) // the tMatrix contains, for every pair, i-j, the t-vector between the centrestMatOneBall(i)=#(j,vSequence(0,nBalls),tVec(i,j),vAppend) // the tMatOneBall vector contains, for every ball, // the the t-vectors between its centre and the other centrestouch(i,j)=((vNormEuclid(@(@(tMat,i),j))<(@(rho,i)+@(rho,j))) && (i!=j) &&

vDot(@(@(tMat,i),j),@(p{1},i)/@(m,i)-@(p{1},j)/@(m,j))>0) // condition for colliding contact. Three terms: // 1. Are the balls close enough? // 2. No self-collision? // 3. Is the relative velocity opposite to the vector connecting the centres?cplOneBall(i)=#(j,vSequence(0,nBalls),cond(touch(i,j),['close':true,'force':(mpt(i,j)/

m1m2tt(i,j))*@(@(tMat,i),j)],['close':false,'force':0]),vAppend) // the cplOneBall vector contains, for ball i, the info for the collisions between this // ball and all other balls. // It sets the value to the boolean 'close', and if close==true, the // current force vector. The derivation of the force vector // is based on conservation of momentum, angular momentum and kinetic energy // in a coordinate-free version.mpt(i,j)=-2*vDot(@(m,j)*@(p{1},i)-@(m,i)*@(p{1},j),@(@(tMat,i),j)) // the product (((m1p2-m2p1)t),t): the numerator of the force vectorm1m2tt(i,j)=(@(m,i)+@(m,j))*vDot(@(@(tMat,i),j),@(@(tMat,i),j)) // the product (m1+m2)(t,t): the denominator of the force vectorf=#(i,vSequence(0,nBalls),forceOnOneBall(i),vAppend) // calculate the forces for all balls by concatenatingforceOnOneBall(i)=#(j,vSequence(0,nBalls),cond(@(@(@(cpl,i),j),'close'),@(@(@(cpl,i),j),'force'),0),add) // adding the forces due to all other of balls rho=#(i,vSequence(0,nBalls),rhoBall,vAppend) // the radii of the balls

m=#(i,vSequence(0,nBalls),mBall,vAppend) // the mass of the ballscol=['red':[255,255,255],'grn':[0,255,255],'blu':[0,255,0]]// colors of the balls: first one is red, two is white, three is yellowishr=if(gameState=='roll',r{1}+dT*p/m,cond(time==1,#(i,vSequence(0,nBalls),['x':halfWay*(random()-

0.5),'y':0.5*halfWay*(random()-0.5)],vAppend),r{1})) // r is obtained by integrating v; at the starting time (==1) give the initial random positions p=if(gameState=='roll',rollDamp*wallCollide(p{1}+f),[['x':0,'y':0],['x':@(@(r{1},1),'x')-

queueX,'y':@(@(r{1},1),'y')-queueY],['x':0,'y':0]]) // p is obtained by tame integrating f; at the starting time give the initial momenta. The only // non-vanishing initial momentum is the momentum of ball 1; this is obtained from the queue position

minus the centre of ball 1.wallCollide(a)=wallCollideLeft(wallCollideRight(wallCollideBottom(wallCollideTop(a)))) // the collisions with all wallswallCollideLeft(a)=#(i,vDom(a),cond((@(@(r{1},i),'x')>(minX+@(rho,i))) || (@(@(a,i),'x')>0),@(a,i),['x':-

collDamp*@(@(a,i),'x'),'y':collDamp*@(@(a,i),'y')]),vAppend)// collide left wallwallCollideRight(a)=#(i,vDom(a),cond((@(@(r{1},i),'x')<(maxX-@(rho,i))) || (@(@(a,i),'x')<0),@(a,i),['x':-

collDamp*@(@(a,i),'x'),'y':collDamp*@(@(a,i),'y')]),vAppend)// collide right wallwallCollideBottom(a)=#(i,vDom(a),cond((@(@(r{1},i),'y')>(minY+@(rho,i))) || (@(@(a,i),'y')>0),@(a,i),

['x':collDamp*@(@(a,i),'x'),'y':-collDamp*@(@(a,i),'y')]),vAppend)// collide bottom wallwallCollideTop(a)=#(i,vDom(a),cond((@(@(r{1},i),'y')<(maxY-@(rho,i))) || (@(@(a,i),'y')<0),@(a,i),

['x':collDamp*@(@(a,i),'x'),'y':-collDamp*@(@(a,i),'y')]),vAppend)// collide top walleKin=#(i,vSequence(0,nBalls),vDot(@(p,i),@(p,i))/(2*@(m,i)),add)// the kinetic energygameState=cond((eKin{1}<eThreshold) && !queueHit,'hit',cond(queueHit,'roll','hit'))// determine which state we are inqueueHit=cursorB()cX=cursorX()cY=cursorY() queueX=cX-halfWayqueueY=cY-halfWay// the queue end position is derived from the location of the cursorplotQueue=cond(gameState=='hit',['plotType:line,col_b:{value:0},col_g:{value:0},col_r:{value:0},x:

{mode:data,ref:1},y:{mode:data,ref:2}',halfWay+[queueX,@(@(r{1},1),'x')],halfWay+[queueY,@(@(r{1},1),'y')]],['plotType:line,x:{mode:data,ref:1},y:{mode:data,ref:2}',[0,0],[0,0]])

plotQueue2=cond(gameState=='hit' && help,['plotType:line,col_g:{value:100},col_r:{value:0},width:{value:0.4},x:{mode:data,ref:1},y:{mode:data,ref:2}',halfWay+[10*(@(@(r{1},1),'x')-queueX)+queueX,@(@(r{1},1),'x')],halfWay+[10*(@(@(r{1},1),'y')-queueY)+queueY,@(@(r{1},1),'y')]],['plotType:line,x:{mode:data,ref:1},y:{mode:data,ref:2}',[0,0],[0,0]])

// the queue is drawn when in hit-modeplotTable=['plotType:vbar,yBase:{value:25},width:{value:80},height:{value:50},col_r:{value:0}',[]]// plot the tableplotBalls=['plotType:bubble,x:{mode:data,ref:1},y:{mode:data,ref:2},diameter:{mode:data,ref:3},col_r:

{mode:data,ref:4},col_g:{mode:data,ref:5},col_b:{mode:data,ref:6}',halfWay+@(vTranspose(r),'x'),halfWay+@(vTranspose(r),'y'),2*rho,@(col,'red'),@(col,'grn'),@(col,'blu')]

// plot the ballsplotShadow=['plotType:bubble,x:{mode:data,ref:1},y:{mode:data,ref:2},diameter:{value:'+2*rhoBall+'},col_r:

{value:0},col_g:{value:0},col_b:{value:0},col_a:{value:0.5}',halfWay-0.15*rhoBall+@(vTranspose(r),'x'),halfWay-0.5*rhoBall+@(vTranspose(r),'y')]

// plot the shadows beneath the ballsplotHighLight=['plotType:bubble,x:{mode:data,ref:1},y:{mode:data,ref:2},diameter:

{value:'+0.75*rhoBall+'},col_r:{value:255},col_g:{value:255},col_b:{value:255}',halfWay+0.1*rhoBall+@(vTranspose(r),'x'),halfWay+0.5*rhoBall+@(vTranspose(r),'y')]

// plot the highlights on the balls

… and a

further

handfull of

details