This is the web version of EJS interface
EJS version 4.3.3.1
  1. Title=Roller Coaster
  2. Author=Michael R Gallis
  3. Abstract=Modified by Wolfgang Christian. Remixed by weelookang@gmail.com
  4. CaptureTools=false
  5. DataTools=false
  6. LanguageTools=false
  7. EmersionSupport=false
  8. AppletColSupport=false
  9. UseInterpreter=true
  10. DetectedFiles=./coaster_car.png;./coaster_spring.png;
    NameValueTypeDimension
    NameValueTypeDimension
    NameValueTypeDimension
    NameValueTypeDimension
    NameValueTypeDimension
    NameValueTypeDimension
    // moved to the fixed realtions by weelk //options ="ramp ;"+"up and down;"+"loop;"+"2loops;"+"figure 8;"+"custom";
    /*if (which_opt=="ramp") set_ramp(); else if (which_opt=="up") set_up_down_up(); else if (which_opt=="loop") set_loop1(); else if (which_opt=="2loops") set_loop2(); else if (which_opt=="figure 8"if () set_fig8(); else if (which_opt=="custom") set_custom(10); // else set_ramp();//if all else fails */ which_opt = which_opts; if (which_opt ==""){ // if blank which_opt = "ramp"; // delta = delta=1.0/(float)N; set_ramp(); }
    // need to disable this cos is it forcing the display to always set_ramp(); by weelk // can't seems to make the applet remember the old state, enable this page back spline_is_natural = true; delta=1.0/(float)N; spline_delta=delta; spline_N=N; for(int i=0;i<=N_max;i++) { interface_x[i]=(float)i/(float)N*20.; interface_y[i]=(float)(N-i)/(float)N*20.; } //set_ramp();/**/
    spline_gamma_init (); spline_getdatay(); spline_getdatax();
    pds0=(float)(N)*delta/(float)pn; plotter ();
    coaster_s=0; coaster_sv=0;
    //t = 0; // appears to be not needed by weelk
    Indep. Var. Increment
    d coaster_s /dt=coaster_sv
    d coaster_sv /dt=sdd(coaster_s,coaster_sv) - friction/mass*coaster_sv
    SolverRungeKutta AbsoluteTolerance=0.00001

    Name:end_of_line,active=true,條件:Method:BISECTION,(誤差範圍0.001),stopatEvent=true
    return 1.0-coaster_s;


    動作
    coaster_sv=-Math.abs(coaster_sv);

    Name:begining_of_line,active=true,條件:Method:BISECTION,(誤差範圍0.001),stopatEvent=true
    return coaster_s;


    動作
    coaster_sv=Math.abs(coaster_sv);

    for(int i=0;i<pn;i++){ ps=pds0*(float)i; px[i]=spline_evaluatorx(ps); pdx[i]=spline_evaluatorx(ps+pds0)-px[i]; py[i]=spline_evaluatory(ps); pdy[i]=spline_evaluatory(ps+pds0)-py[i]; }
    options ="ramp;"+"up and down;"+"circularloop;"+"loop;"+"2loops;"+"figure 8;"+"custom"; /* if (which_opt.startsWith("ramp")) set_ramp(); else if (which_opt.startsWith("up")) set_up_down_up(); else if (which_opt.startsWith("loop")) set_loop1(); else if (which_opt.startsWith("2loops")) set_loop2(); else if (which_opt.startsWith("figure 8")) set_fig8(); else if (which_opt.startsWith("custom")) set_custom(10); // else set_ramp();//if all else fails */ /* if (which_opt=="ramp") set_ramp(); else if (which_opt=="up") set_up_down_up(); else if (which_opt=="loop") set_loop1(); else if (which_opt=="2loops") set_loop2(); else if (which_opt=="figure 8") set_fig8(); else if (which_opt=="custom") set_custom(10); else set_ramp();//if all else fails */
    controls_limits ();
    coaster_set ();
    PE = mass*g*ys(coaster_s); // added by weelk for ease of variables KE=.5*mass*coaster_v*coaster_v; E = PE+KE;
    //add x-zero offset later public double spline_evaluatory(double this_s) { double scaled_s=this_s/spline_delta; int is=(int)(scaled_s); is = Math.min(Math.max(is,0),spline_N-1); double zz=scaled_s-(float)is; double val=spline_ay[is]+(spline_by[is]+(spline_cy[is]+spline_dy[is]*zz)*zz)*zz; return val; } //evaluate y spline parameters from knots public void spline_getdatay() { spline_N=N; //no bounds checking here... for(int i=0;i<=spline_N;i++) { spline_fy[i]=interface_y[i]; } spline_chiy[0]=spline_beta*(spline_fy[1]-spline_fy[0]); spline_phiy[0]=spline_chiy[0]; for(int i=1;i<=spline_N-1;i++) { spline_chiy[i]=3.0*(spline_fy[i+1]-spline_fy[i-1]); spline_phiy[i]=spline_gamma[i]*(spline_chiy[i]-spline_phiy[i-1]); } spline_chiy[spline_N]=spline_beta*(spline_fy[spline_N]-spline_fy[spline_N-1]); spline_phiy[spline_N]=spline_gamma[spline_N]*(spline_chiy[spline_N]-spline_alpha*spline_phiy[spline_N-1]); spline_Dy[spline_N]=spline_phiy[spline_N]; for(int i=1;i<=spline_N;i++) { spline_Dy[spline_N-i]=spline_phiy[spline_N-i]-spline_gamma[spline_N-i]*spline_Dy[spline_N-i+1]; } for(int i=0;i<=spline_N-1;i++) { spline_ay[i]=spline_fy[i]; spline_by[i]=spline_Dy[i]; spline_cy[i]=3.0*(spline_fy[i+1]-spline_fy[i])-spline_Dy[i+1]-2.0*spline_Dy[i]; spline_dy[i]=spline_Dy[i+1]+spline_Dy[i]-2.0*(spline_fy[i+1]-spline_fy[i]); } } //initialize spline constants for this number of knots and type of spline public void spline_gamma_init () { if(spline_is_natural) { spline_alpha=.5; spline_beta=1.5; } else { spline_alpha=1; spline_beta=2; } spline_gamma[0]=spline_alpha; for(int i=1;i<=spline_N-1;i++) { spline_gamma[i]=1.0/(4.0-spline_gamma[i-1]); } spline_gamma[spline_N]=1.0/(1.0-spline_alpha*spline_gamma[spline_N-1]); }
    //add x-zero offset later public double spline_evaluatorx(double this_s) { double scaled_s=this_s/spline_delta; int is=(int)(scaled_s); is = Math.min(Math.max(is,0),spline_N-1); double zz=scaled_s-(float)is; double val=spline_ax[is]+(spline_bx[is]+(spline_cx[is]+spline_dx[is]*zz)*zz)*zz; return val; } //evaluate x spline parameters from knots public void spline_getdatax() { spline_N=N; //no bounds checking here... for(int i=0;i<=spline_N;i++) { spline_fx[i]=interface_x[i]; } spline_chix[0]=spline_beta*(spline_fx[1]-spline_fx[0]); spline_phix[0]=spline_chix[0]; for(int i=1;i<=spline_N-1;i++) { spline_chix[i]=3.0*(spline_fx[i+1]-spline_fx[i-1]); spline_phix[i]=spline_gamma[i]*(spline_chix[i]-spline_phix[i-1]); } spline_chix[spline_N]=spline_beta*(spline_fx[spline_N]-spline_fx[spline_N-1]); spline_phix[spline_N]=spline_gamma[spline_N]*(spline_chix[spline_N]-spline_alpha*spline_phix[spline_N-1]); spline_Dx[spline_N]=spline_phix[spline_N]; for(int i=1;i<=spline_N;i++) { spline_Dx[spline_N-i]=spline_phix[spline_N-i]-spline_gamma[spline_N-i]*spline_Dx[spline_N-i+1]; } for(int i=0;i<=spline_N-1;i++) { spline_ax[i]=spline_fx[i]; spline_bx[i]=spline_Dx[i]; spline_cx[i]=3.0*(spline_fx[i+1]-spline_fx[i])-spline_Dx[i+1]-2.0*spline_Dx[i]; spline_dx[i]=spline_Dx[i+1]+spline_Dx[i]-2.0*(spline_fx[i+1]-spline_fx[i]); } }
    public void plotter () { for(int i=0;i<pn;i++) { ps=pds0*(float)i; px[i]=spline_evaluatorx(ps); pdx[i]=spline_evaluatorx(ps+pds0)-px[i]; py[i]=spline_evaluatory(ps); pdy[i]=spline_evaluatory(ps+pds0)-py[i]; } }
    public void controls_limits () { N=Math.min(N_max,Math.max(0,N)); for(int i=0;i<=N_max;i++) { interface_x[i]=Math.min(20.0,Math.max(interface_x[i],0.0)); interface_y[i]=Math.min(20.0,Math.max(interface_y[i],0.0)); } } public void update_spline() { //stuff that needs to be called when spline is changed //set the spline controls_limits (); spline_getdatay(); spline_getdatax(); //update the stuff for dynamics including stuff for display KE=.5*mass*coaster_v0*coaster_v0; // KE = 0.5*m*v*v added by weelk E=mass*g*ys(0.0)+KE; // TE = mgh + KE added by weelk double xp=xsp(0.);//only evaluate these once... double yp=ysp(0.); coaster_sv0=coaster_v0/Math.sqrt(xp*xp+yp*yp); coaster_reset(); //track/launch speed change ->reset cart to start } public void play_it() { //update_spline(); _play(); } public void pause_it() { _pause(); }
    //this function evaluates x as a function of s public double xs(double this_s) { double scaled_s=this_s/spline_delta; int is=(int)(scaled_s); is = Math.min(Math.max(is,0),spline_N-1); double zz=scaled_s-(float)is; double val=spline_ax[is]+(spline_bx[is]+(spline_cx[is]+spline_dx[is]*zz)*zz)*zz; return val; } //this function evaluates the the first derivative of x wrt s public double xsp(double this_s) { double scaled_s=this_s/spline_delta; int is=(int)(scaled_s); is = Math.min(Math.max(is,0),spline_N-1); double zz=scaled_s-(float)is; double val=spline_bx[is]+(2.0*spline_cx[is]+3.0*spline_dx[is]*zz)*zz; return val/spline_delta; } //this function evaluates the the second derivative of x wrt s public double xspp(double this_s) { double scaled_s=this_s/spline_delta; int is=(int)(scaled_s); is = Math.min(Math.max(is,0),spline_N-1); double zz=scaled_s-(float)is; double val=2.0*spline_cx[is]+6.0*spline_dx[is]*zz; return val/(spline_delta*spline_delta); } //this function evaluates y as a function of s public double ys(double this_s) { double scaled_s=this_s/spline_delta; int is=(int)(scaled_s); is = Math.min(Math.max(is,0),spline_N-1); double zz=scaled_s-(float)is; double val=spline_ay[is]+(spline_by[is]+(spline_cy[is]+spline_dy[is]*zz)*zz)*zz; return val; } //this function evaluates the the first derivative of y wrt s public double ysp(double this_s) { double scaled_s=this_s/spline_delta; int is=(int)(scaled_s); is = Math.min(Math.max(is,0),spline_N-1); double zz=scaled_s-(float)is; double val=spline_by[is]+(2.0*spline_cy[is]+3.0*spline_dy[is]*zz)*zz; return val/spline_delta; } //this function evaluates the the second derivative of y wrt s public double yspp(double this_s) { double scaled_s=this_s/spline_delta; int is=(int)(scaled_s); is = Math.min(Math.max(is,0),spline_N-1); double zz=scaled_s-(float)is; double val=2.0*spline_cy[is]+6.0*spline_dy[is]*zz; return val/(spline_delta*spline_delta); } //this function evaluates the the second derivative of s wrt time public double sdd(double s, double sd) { double xp=xsp(s);//only evaluate these once... double yp=ysp(s); // from description dynamics dcoaster_sv/dt = -g*yp .... double val=-g*yp-1.0*(xp*xspp(s)+yp*yspp(s))*sd*sd; // double val=-mass*g*yp-1.0*(xp*xspp(s)+yp*yspp(s))*sd*sd; // added mass val=val/(xp*xp+yp*yp); return val; }
    /* options = "ramp ;"+ "up and down;"+ "loop;"+ "2loops;"+ "figure 8;"+ "custom"; */ public void service_opts() { showN=false; if (which_opt.startsWith("ramp")) set_ramp(); else if (which_opt.startsWith("up")) set_up_down_up(); else if (which_opt.startsWith("loop")) set_loop1(); else if (which_opt.startsWith("circularloop")) set_loopcircular(); // added by lookang for circular loop else if (which_opt.startsWith("2loops")) set_loop2(); else if (which_opt.startsWith("figure 8")) set_fig8(); else if (which_opt.startsWith("custom")) set_custom(10); else set_ramp();//if all else fails } public void set_custom(int N) { showN=true; this.N=N; delta=1.0/(float)N; spline_delta=delta; spline_N=N; for(int i=0;i<=N_max;i++) { interface_x[i]=(float)i/(float)N*20.; interface_y[i]=(float)(N-i)/(float)N*20.; } spline_gamma_init (); update_spline(); pds0=(float)(N)*delta/(float)pn; plotter (); which_opts = "custom"; // added in attempt in make it remember by weelk } public void set_ramp() { N=7; delta=1.0/(float)N; spline_delta=delta; spline_N=N; for(int i=0;i<=N_max;i++) { interface_x[i]=(float)i/(float)N*20.; interface_y[i]=(float)(N-i)/(float)N*20.; } spline_gamma_init (); update_spline(); pds0=(float)(N)*delta/(float)pn; plotter (); which_opts = "ramp"; // added in attempt in make it remember by weelk } public void set_up_down_up() { coaster_s=0.; _reset(); N=5; delta=1.0/(float)N; spline_delta=delta; spline_N=N; interface_x[0]=0.; interface_y[0]=20.; interface_x[1]=4.; interface_y[1]=10.; interface_x[2]=8.; interface_y[2]=0.; interface_x[3]=12.; interface_y[3]=0.; interface_x[4]=16.; interface_y[4]=10.; interface_x[5]=20.; interface_y[5]=20.; spline_gamma_init (); /* spline_getdatay(); spline_getdatax(); */ update_spline(); pds0=(float)(N)*delta/(float)pn; plotter (); which_opts = "up"; // added in attempt in make it remember by weelk } public void set_loop1() { coaster_s=0.; _reset(); N=7; delta=1.0/(float)N; spline_delta=delta; spline_N=N; interface_x[0]=0.; interface_y[0]=20.; interface_x[1]=3.; interface_y[1]=0.; interface_x[2]=15.; interface_y[2]=0.; interface_x[3]=15.; interface_y[3]=11.; interface_x[4]=3.; interface_y[4]=11.; interface_x[5]=3.; interface_y[5]=0.; interface_x[6]=15.; interface_y[6]=0.; interface_x[7]=20.; interface_y[7]=20.; spline_gamma_init (); /* spline_getdatay(); spline_getdatax(); */ update_spline(); pds0=(float)(N)*delta/(float)pn; plotter (); which_opts = "loop"; // added in attempt in make it remember by weelk } public void set_loopcircular() { // circular added by lookang coaster_s=0.; _reset(); N=25; delta=1.0/(float)N; spline_delta=delta; spline_N=N; interface_x[0]=0.; interface_y[0]=20.; interface_x[1]=0.5; interface_y[1]=9.; interface_x[2]=1.6; interface_y[2]=4.5; interface_x[3]=2.9; interface_y[3]=2.1; interface_x[4]=5.5; interface_y[4]=0.5; for (int counter=5; counter<=(18+4) /* Iterations */ ; counter++) { interface_x[counter]=10+Radius*Math.cos(((counter-5)*20.-90.)/180.*Math.PI); interface_y[counter]=5+Radius*Math.sin(((counter-5)*20.-90)/180.*Math.PI); } interface_x[23]=11.; interface_y[23]=0.; interface_x[24]=15.; interface_y[24]=0.; interface_x[25]=20.; interface_y[25]=0.; spline_gamma_init (); /* spline_getdatay(); spline_getdatax(); */ update_spline(); pds0=(float)(N)*delta/(float)pn; plotter (); which_opts = "circularloop"; // added in attempt in make it remember by weelk } public void set_loop2() { coaster_s=0.; _reset(); N=12; delta=1.0/(float)N; spline_delta=delta; spline_N=N; interface_x[0]=0.; interface_y[0]=20.; interface_x[1]=5.; interface_y[1]=10.; interface_x[2]=10.; interface_y[2]=10.; interface_x[3]=10.; interface_y[3]=15.; interface_x[4]=5.; interface_y[4]=15.; interface_x[5]=5.; interface_y[5]=1.; interface_x[6]=10.; interface_y[6]=1.; interface_x[7]=10.; interface_y[7]=6.; interface_x[8]=5.; interface_y[8]=6.; interface_x[9]=5.; interface_y[9]=1.; interface_x[10]=10.; interface_y[10]=1.; interface_x[11]=15.; interface_y[11]=10.; interface_x[12]=18.; interface_y[12]=20.; spline_gamma_init (); spline_getdatay(); spline_getdatax(); pds0=(float)(N)*delta/(float)pn; plotter (); which_opts = "2loops"; // added in attempt in make it remember by weelk } public void set_fig8() { coaster_s=0.; _reset(); N=12; delta=1.0/(float)N; spline_delta=delta; spline_N=N; interface_x[0]=0.; interface_y[0]=20.; interface_x[1]=2.; interface_y[1]=4.; interface_x[2]=6.; interface_y[2]=0.; interface_x[3]=10.; interface_y[3]=4.; interface_x[4]=6.; interface_y[4]=8.; interface_x[5]=2.; interface_y[5]=4.; interface_x[6]=6.; interface_y[6]=0.; interface_x[7]=10.; interface_y[7]=4.; interface_x[8]=14.; interface_y[8]=8.; interface_x[9]=18.; interface_y[9]=4.; interface_x[10]=14.; interface_y[10]=0.; interface_x[11]=10.; interface_y[11]=4.; interface_x[12]=14.; interface_y[12]=20.; spline_gamma_init (); /* spline_getdatay(); spline_getdatax(); */ update_spline(); pds0=(float)(N)*delta/(float)pn; plotter (); which_opts = "figure 8"; // added in attempt in make it remember by weelk }
    public void coaster_set () { coaster_x=xs(coaster_s); coaster_y=ys(coaster_s); coaster_vx=xsp(coaster_s)*coaster_sv; coaster_vy=ysp(coaster_s)*coaster_sv; coaster_v=Math.sqrt(coaster_vx*coaster_vx+coaster_vy*coaster_vy); v_display = String.format("V = %4.1f", coaster_v); coaster_theta=Math.atan2(ysp(coaster_s),xsp(coaster_s)); coaster_ax=xspp(coaster_s)*coaster_sv*coaster_sv+xsp(coaster_s)*coaster_sa; coaster_ay=yspp(coaster_s)*coaster_sv*coaster_sv+ysp(coaster_s)*coaster_sa; Rx=mass*coaster_ax; // Reaction forcex = mass*coaster_ax Ry=mass*(coaster_ay+g); // added mass by weelk //fix reaction force -take only components perp to track vhat_x=xsp(coaster_s);//tangent unit vector vhat_y=ysp(coaster_s); vn=Math.sqrt(vhat_x*vhat_x+vhat_y*vhat_y); vhat_x=vhat_x/vn; vhat_y=vhat_y/vn; nhat_x=-vhat_y;// track norml = tangent rotated 90 degrees nhat_y=vhat_x; rdn=Rx*nhat_x+Ry*nhat_y; Rx=rdn*nhat_x; Ry=rdn*nhat_y; //set spring spring_x=xs(.999); spring_y=ys(.999); spring_theta=Math.atan2(ysp(.999),xsp(.999)); //set launcher launcher_x=xs(.0); launcher_y=ys(.0); launcher_theta=Math.atan2(ysp(.0),xsp(.0))+3.14159; } public void coaster_reset() { coaster_s=0; coaster_sv=coaster_sv0; t=0; }
    EJSVIEW: Click link to view it's content
    Control variables:(testing)
    double,double,double,double,double,double,double,double,double
    title="Roller Coaster Physics Model"
    layout=BORDER:0,0
    visible=true
    location="321,329"
    size="700,540"
    position=center
    autoscaleX=false
    autoscaleY=false
    minimumX=-5.0
    maximumX=25.
    minimumY=-5.0
    maximumY=25.0
    square=true
    showCoordinates=true
    background=220,245,255
    x=0
    y=0
    sizex=90
    sizey=10
    enabled=true
    style=RECTANGLE
    elementposition=NORTH
    color=255,128,64
    x=coaster_x
    y=coaster_y
    sizex=4
    sizey=4
    enabled=true
    image=./coaster_car.png
    angle=coaster_theta
    elementnumber=pn
    x=px
    y=py
    sizex=pdx
    sizey=pdy
    visible=true
    enabledSecondary=false
    enabled=false
    style=SEGMENT
    color=GRAY
    stroke=2
    x=coaster_x
    y=coaster_y
    sizex=coaster_vx
    sizey=coaster_vy
    scalex=.5
    scaley=.5
    visible=true
    enabledSecondary=false
    enabled=false
    color=MAGENTA
    secondaryColor=MAGENTA
    x=coaster_x
    y=coaster_y
    sizex=Rx
    sizey=Ry
    scalex=.25
    scaley=.25
    visible=true
    enabledSecondary=false
    enabled=false
    style=ARROW
    color=GREEN
    secondaryColor=GREEN
    stroke=2
    x=coaster_x
    y=coaster_y
    sizey=-g
    scalex=.25
    scaley=.25
    visible=true
    enabledSecondary=false
    enabled=false
    style=ARROW
    color=RED
    secondaryColor=RED
    x=coaster_x
    y=coaster_y
    sizey=-g*1.2
    scalex=.25
    scaley=.25
    visible=true
    enabledSecondary=false
    enabled=false
    style=ARROW
    color=RED
    secondaryColor=RED
    x=spring_x
    y=spring_y
    sizex=4
    sizey=4
    visible=true
    enabled=false
    image=./coaster_spring.png
    angle=spring_theta
    x=coaster_x+Rx*.3
    y=coaster_y+Ry*.3
    enabled=false
    text="R"
    color=GREEN
    x=coaster_x+0.5
    y=coaster_y-.3*g
    enabled=false
    text="g"
    elementposition=WEST
    color=RED
    x=coaster_x+.55*coaster_vx
    y=coaster_y+.55*coaster_vy
    enabled=false
    text="v"
    color=MAGENTA
    x=launcher_x
    y=launcher_y
    sizex=4
    sizey=4
    visible=true
    enabled=false
    image=./coaster_spring.png
    angle=launcher_theta
    elementnumber=N+1
    x=interface_x
    y=interface_y
    sizex=.5
    sizey=.5
    size=1.0
    visible=_isPaused()
    enabled=_isPaused()
    dragaction=update_spline ()
    x=-5
    y=-3
    visible=false
    enabled=false
    text=%v_display%
    elementposition=WEST
    color=MAGENTA
    position=south
    layout=VBOX
    borderType=LOWERED_ETCHED
    position=center
    layout=HBOX
    layout=HBOX
    variable=coaster_v0
    value=0.0
    minimum=-10
    maximum=10
    format="u = 0.0 m/s"
    ticks=21
    dragaction=update_spline ()
    background=MAGENTA
    layout=border
    visible=showN
    position=west
    text=" N"
    position=center
    variable=N
    format=0
    action=N=Math.max(2,N); N=Math.min(N,spline_Nmax); // limit the maximum set_custom(N);
    size="50,24"
    layout=HBOX
    tooltip="doesnt work"
    variable=g
    minimum=-9.81
    maximum=19.62
    format="g = 0.0 m/s^2"
    enabled=true
    dragaction=update_spline (); _initialize();
    background=RED
    variable=mass
    value=1
    minimum=1
    maximum=10
    format="m = 00 kg"
    ticks=11
    dragaction=update_spline (); _initialize();
    tooltip="mass of roller coaster in kg"
    variable=friction
    value=0
    minimum=0.0
    maximum=5
    format="b = 0.0 N"
    ticks=11
    dragaction=_initialize();
    visible=false
    tooltip="damping factor b, where Fdamping = b*v"
    layout=HBOX
    variable=t
    minimum=0.0
    maximum=10
    format="t = 0.00 s"
    enabled=false
    layout=HBOX
    variable=coaster_v
    minimum=0.0
    maximum=20
    format="v = 0.0 m/s"
    enabled=false
    background=MAGENTA
    layout=HBOX
    visible=false
    variable=E
    minimum=0.0
    maximum=196.2
    format="TE = 0.0 J"
    enabled=false
    layout=HBOX
    visible=false
    variable=PE
    minimum=0.0
    maximum=196.2
    format="PE = 0.0 J"
    enabled=false
    foreground=BLUE
    layout=HBOX
    visible=false
    variable=KE
    minimum=0.0
    maximum=196.2
    format="KE = 0.0 J"
    enabled=false
    foreground=MAGENTA
    position=west
    layout=HBOX
    layout=BORDER:0,0
    borderTitle="examples: "
    position=center
    options=%options%
    variable=%which_opt%
    action=service_opts()
    size=150,24
    editBackground=WHITE
    background=WHITE
    font=Monospaced,PLAIN,12
    tooltip="Select an example roller coaster track"
    variable=mom_graph
    text="plot v vs t"
    foreground=255,0,255,200
    variable=KE_graph
    text="plot KE vs t"
    foreground=255,0,255,100
    layout=HBOX
    variable=_isPaused
    tooltip="Starts and stops the simulation."
    imageOn=/org/opensourcephysics/resources/controls/images/play.gif
    actionOn=_play()
    imageOff=/org/opensourcephysics/resources/controls/images/pause.gif
    actionOff=_pause()
    image=/org/opensourcephysics/resources/controls/images/step.gif
    action=_step()
    tooltip="Steps the simulation."
    image=/org/opensourcephysics/resources/controls/images/reset1.gif
    action=coaster_reset ()
    tooltip="Resets the time."
    image=/org/opensourcephysics/resources/controls/images/reset.gif
    action=//coaster_s=0.; _reset(); _view.presets_combo.setSelectedIndex(0);
    tooltip="Resets the simulation to its default state."
    position=west
    layout=HBOX
    position=center
    layout=VBOX
    variable=E
    minimum=0.0
    maximum=196.2
    format="TE = 0.0 J"
    orientation=VERTICAL
    foreground=BLACK
    tooltip="total energy"
    position=north
    layout=VBOX
    variable=g*ys(coaster_s)
    minimum=0.0
    maximum=196.2
    format="PE = 0.0 J"
    orientation=VERTICAL
    foreground=BLUE
    position=south
    layout=VBOX
    variable=KE
    minimum=0.0
    maximum=196.2
    format="KE = 0.0 J"
    orientation=VERTICAL
    foreground=MAGENTA
    position=east
    layout=VBOX
    layout=VBOX
    visible=mom_graph
    position=center
    autoscaleX=true
    autoscaleY=true
    minimumX=0
    yMarginPercentage=5
    title="velocity ( m/s) vs time (s)"
    showAxes=true
    axesType=CARTESIAN2
    titleX="time (s)"
    titleY="velocity ( m/s)"
    visible=mom_graph
    x=t
    y=coaster_v
    active=true
    norepeat=true
    connected=true
    color=MAGENTA
    stroke=1
    layout=VBOX
    autoscaleX=true
    autoscaleY=true
    minimumX=0
    yMarginPercentage=5
    title="energy (J) vs time (s)"
    showAxes=true
    axesType=CARTESIAN2
    titleX="time (s)"
    titleY="energy (J)"
    visible=KE_graph
    x=t
    y=E
    active=true
    norepeat=true
    connected=true
    color=BLACK
    stroke=1
    x=t
    y=PE
    active=true
    norepeat=true
    connected=true
    color=BLUE
    stroke=1
    x=t
    y=KE
    active=true
    norepeat=true
    connected=true
    color=MAGENTA
    stroke=1