Download or view 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]
Download or view 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 20217 days, 23 hours, 57 minutes ago.