derbytrack2.frink

View or download derbytrack2.frink in plain text format


/** 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]


View or download derbytrack2.frink in plain text format


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 17628 days, 11 hours, 55 minutes ago.