# derbytrack2.frink

``` /** This program renders a track for womens' flat-track roller derby.     Main rules page:       http://wftda.com/rules     Appendix B specifies track layout process:       http://wftda.com/rules/wftda-rules-appendix-b-track-design.pdf    Note that the inner boundary is symmetrical about the x and y axes, but    the outer boundary is not.  The entry to the curves is 2 feet narrower than    the exits to the curves. */ use geometry.frink use Derby.frink //input["press enter"] g = new graphics g.color[.5,.5,.5] p = new filledGeneralPath // Draw inside ring p.moveTo[12.5, -17.5] p.lineTo[12.5,  17.5] p.circularArc[0, 17.5, -180 degrees] p.lineTo[-12.5, -17.5] p.circularArc[0, -17.5, -180 degrees] p.close[] // Draw outside ring (in opposite winding direction.) p.moveTo[25.5, -17.5] p.circularArc[-1, -17.5, 180 degrees] p.lineTo[-25.5, 17.5] p.circularArc[1, 17.5, 180 degrees] p.close[] g.add[p] g.color[1, .4, .4, .7] g.stroke[3/12] y = -17.5 xo = 25.5 // The track narrows by 2 feet along the direction of travel in straightaways, // which are 35 feet long. sideslope = 35/2 // Draw lines on right side.  First is pivot line for n = 1 to 4 {    g.line[12.5, y, xo, y]    y = y + 10    xo = xo + 10 / sideslope } // Draw lines on left side. y = 17.5 xo = -25.5 for n = 1 to 4 {    g.line[-12.5, y, xo, y]    y = y - 10    xo = xo - 10 / sideslope } // Draw lines in curves rin = 12.5 rout1 = 25.5 rout2 = 27.5 c = (7 feet + 1/2 in) / feet // Center of the inner ring cx = 0 cy = -17.5 // Center of the outer ring, which is offset from the inner ring. cx1 = -1 cy1 = -17.5 r1 = 26.5 for n = 1 to 5 {    theta = 2 n arcsin[c/(2 rin)]    // Translate the chord to angle.    x1 = rin   cos[theta] + cx    y1 = cy - rin   sin[theta]    sols = circleLineIntersections[cx, cy, x1, y1, cx1, cy1, r1]        g.line[ x1,  y1,  sols@1@0,  sols@1@1]    g.line[-x1, -y1, -sols@1@0, -sols@1@1] } /** This program draws and tests the roller derby coordinate system defined     in Derby.frink. */ black = new color[0,0,0] blue = new color[0,0,1] gray = new color[0,0,0,.5] for d = 0 to Derby.d4 step 1    // This gives one entire loop of the track {    // Inside of track (w=0)    g.color[black]    [x,y] = Derby.WDtoXY[0,d]    g.fillEllipseCenter[x,y,.5,.5]    // Outside of track (w=1)    [x,y] = Derby.WDtoXY[1,d]    g.fillEllipseCenter[x,y,.5,.5]    // Middle of track (w = 0.5)    g.color[gray]    [x,y] = Derby.WDtoXY[0.5,d]    g.fillEllipseCenter[x,y,.5,.5]        // Effective track length (w = Derby.effectiveW)    g.color[blue]    [x,y] = Derby.WDtoXY[Derby.effectiveW, d]    g.fillEllipseCenter[x,y,.5,.5] } /* Draw 10-foot lines all the way around the track.    Note that the jammer line is at d=5 so we start there. */ for d=5 to Derby.d4+5 step 10 {    [x1,y1] = Derby.WDtoXY[0, d]    [x2,y2] = Derby.WDtoXY[1, d]    g.line[x1, y1, x2, y2] } // Redraw the jammer line and pivot line in red. g.color[1,0,0,.8] // Jammer line is w=[0,1], d=5. [x1,y1] = Derby.WDtoXY[0,5] [x2,y2] = Derby.WDtoXY[1,5] g.line[x1,y1,x2,y2] // Pivot line is w=[0,1], d=35. [x1,y1] = Derby.WDtoXY[0,35] [x2,y2] = Derby.WDtoXY[1,35] g.line[x1,y1,x2,y2]1 //g.show[] //g.write["derbytrack.html", 800, 800] //browse["derbytrack.html"] g2 = new graphics win = g2.show[800,600,1] lastTime = now[] startW = 0.5 startD = 4 vx = 0 ft /s vy = 0 ft/s lastvx = vx lastvy = vy trackDistance = randomFloat[10,40] [lastX, lastY] = Derby.WDtoXY[startW, startD] nominalDelay = 1/30 s for d = startD to 4 Derby.d4 + 6 step 1/2 {    g2 = new graphics    /*g2.saveTransform[]    g2.translate[60,0]    g2.scale[1/2,1/2]    g2.add[g]    g2.restoreTransform[]*/        g2.add[g]    w = 0.5 + .4 sin[d/trackDistance]    [x,y] = Derby.WDtoXY[w, d]        // Hey let's be nerds and calculate actual physical velocities of our sim //   time = now[] //   delay = time - lastTime //   lastTime = time    dx = (x-lastX) feet    dy = (y-lastY) feet    trackAngle = arctan[dy,dx]    // Draw the skater    g2.saveTransform[]    g2.rotate[trackAngle,x,y]    g2.color[1,1,0,.9]    g2.fillRectCenter[x, y, 2, 2]    g2.restoreTransform[]        distance = sqrt[dx^2 + dy^2]  // Distance traveled this timestep    speed = distance/nominalDelay    vx = dx / nominalDelay    vy = dy / nominalDelay    dvx = (vx - lastvx) / nominalDelay    dvy = (vy - lastvy) / nominalDelay    // Calculate acceleration and lean angle.    a = sqrt[dvx^2 + dvy^2]    angle = arctan[a/gee] //   println[angle] //   println[speed] //   println[a]    g2.saveTransform[]    g2.translate[4,0]    g2.color[black]    g2.line[0,10,4 sin[angle], 10 - 4 cos[angle]]    g2.restoreTransform[]        g2.font["Monospaced", 3]    g2.text[padLeft[format[speed, "mph", 2], 9, " "], 0, 0]    g2.text[padLeft[format[a, "gee", 2], 9, " "], 0, 3] //   g2.text[padLeft[format[vx, "mph", 2], 9, " "], 0, 6] //   g2.text[padLeft[format[vy, "mph", 2], 9, " "], 0, 9] //   g2.text[padLeft[format[dvx, "gee", 2], 9, " "], 0, 6]    lastX = x    lastY = y    lastvx = vx    lastvy = vy    win.replaceGraphics[g2]    sleep[nominalDelay] } //g2.write["track.svg",400,800] //g2.write["track.html",400,800] ```

This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 19092 days, 8 hours, 30 minutes ago.