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 17958 days, 2 hours, 51 minutes ago.