# 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 18864 days, 10 hours, 34 minutes ago.