Post on 27-Dec-2015
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