/** This file converts between x,y coordinates and "track" coordinates for
Womens' Flat-Track Roller Derby. The layout for the track is specified in
the document: Appendix A: WFTDA Track Design and Specifications, which
is available at:
http://static.wftda.com/rules/wftda-rules-appendix-a-track-design.pdf
The [x,y] coordinates are coordinates obtained from looking down on the
track from above, with the curves at top and bottom, as demonstrated in
Figure 1 of the above document, with the center of the track at [0,0]
and the jammer and pivot lines on the right. The [x,y] coordinates are in
feet, with x increasing to the right, and y increasing downwards.
The [w,d] coordinates are values of my own devising where w is the
sideways distance along the track, going from w=0 on the inside of the
in-bounds track to w=1 on the outside of the in-bounds track. The d
coordinate is the distance along the track in feet, with the nominal
distance around curves being defined in an interesting and
not-very-obvious way that falls out of the track definition rules. This
will be discussed in more detail later.
The jammer line is at d=5.
The pivot line is at d=35, which is the exact beginning of the "first
curve".
In the [w,d] coordinate system, the first straightaway has its beginning
at d=0, which is 5 feet behind the jammer line. The "first curve" means
the entire first curved section of the track after this, or the top curve
in Figure 1 or 2 of the aforementioned WFTDA document.
In the [w,d] coordinate system:
* The first straightaway runs from d=0 to Derby.d1
* The first curve runs from Derby.d1 to Derby.d2
* The second straightaway runs from Derby.d2 to Derby.d3
* The second curve runs from Derby.d3 to Derby.d4
(Exact constants for these distances can be obtained from the program
below.)
This file contains conversion routines for converting between [x,y] and
[w,d] coordinate systems. The [x,y] system is useful for, say,
determining where to draw a skater on the track, or finding out where a
user clicked, and the [w,d] coordinates are good for simulating motion
along the in-bounds section of the track. The side-to-side position along
the track is given by varying w from 0 to 1, and the forward motion along
the track is given by varying d from 0 to Derby.d4, which indicates a
complete loop around the track.
Many more explanations of the coordinate systems and the internal
variables are forthcoming. These may require a vast treatise on the
oddities that the track layout rules imply.
Thanks very much to Denise Dambrackas/"Fawn Stalking" of the Denver Roller
Dolls for expert discussion of rules and layout, and general awesomeness.
*/
class Derby
{
/** Length of a straightaway. */
class var straightaway = 35
/** Inner radius of curves. */
class var inR = 12.5
/** Length of inner arc */
class var inArc = inR pi
/** This is the angle that is generated between 10 foot lines in curves if
the rules in Appendix B: WFTDA Track Design and Specifications are
followed.
Calculated value = 32.71940 degrees.
*/
class var tenFootAngle = 2 arcsin[((7 feet + 1/2 in)/feet)/(2 inR)]
/** This calculation reverse-engineers the radius of the track for which the
10-foot lines in the curves are actually 10 feet apart.
Calculated value: 17.511254 ft
*/
class var effectiveRadius = 10 / tenFootAngle
/** This is the effective length of each curve if you follow a path where
the 10-foot lines in the curves are actually 10 feet apart.
Calculated value: 55.0132277 ft
*/
class var midArc = effectiveRadius pi
/** This is the effective w-coordinate of the effective 10-foot-line.
Calculated value: 0.3579467 */
class var effectiveW = (effectiveRadius-inR)/14
/** d of end of first straightaway. Calculated value: d1 = 35 */
class var d1 = straightaway
/** d of end of first curve. Calculated value: d2 = 90.0132277 */
class var d2 = d1 + midArc
/** d of end of second straightaway. Calculated value: d3 = 125.0132277 */
class var d3 = d2 + straightaway
/** d of end of second curve Calculated value: d4 = 180.0264554
This is the effective length of the track if you follow the
"effectiveW" path where the 10-foot lines are actually spaced at
10-foot intervals around the curve. */
class var d4 = d3 + midArc
/** Convert from x,y coordinates to w,d coordinates */
class XYtoWD[x,y] :=
{
if y < -17.5 // First curve
{
theta = arctan[-(y+17.5), x]
r = sqrt[x^2 + (y+17.5)^2]
w = (r - 12.5) / (13 + 2 theta / pi)
d = d1 + effectiveRadius theta
return [w, d]
}
if y > 17.5 // Second curve
{
theta = arctan[y-17.5,-x]
r = sqrt[x^2 + (y-17.5)^2]
w = (r-12.5) / (13 + 2 theta / pi)
d = d3 + effectiveRadius theta
return [w, d]
}
if x > 0 // First straight
return [(x-12.5)/(y/17.5 + 14), // w
17.5 - y] // d
else // second straight
return [-(12.5 + x) / (-y/17.5 + 14), // w
d2 + y + 17.5] // d
}
/** Convert from w,d coordinates to x,y coordinates. */
class WDtoXY[w, d] :=
{
d = d mod d4
// First straight
if d < d1
return [12.5 + (15 - d/17.5) w, // x
17.5 - d] // y
// First curve
if d < d2
{
theta = (d - d1) / effectiveRadius
r = 12.5 + w (13 + 2 theta/pi)
inside = cos[theta]^2 sqrt[r^2 sec[theta]^2 tan[theta]^2]
// Cotangent goes to infinity around 0 and pi, so work around it
if abs[theta] < 1e-6
return[12.5 + 13 w, -17.5]
if abs[theta-pi] < 1e-6
return[-12.5 - 15 w, -17.5]
x = cot[theta] inside
y = -17.5 - inside
return [x,y]
}
// Second straight
if (d < d3)
{
x = -12.5 + 1/35 (2 d - 2 d2 - 525) w
y = d - d2 - 17.5
return [x,y]
}
// Second curve
theta = (d - d3) / effectiveRadius
// Cotangent goes to infinity around 0 and pi, so work around it
if abs[theta] < 1e-6
return[-12.5 - 13 w, 17.5]
if abs[theta-pi] < 1e-6
return[12.5 + 15 w, 17.5]
r = 12.5 + w (13 + 2 theta/pi)
inside = cos[theta]^2 sqrt[r^2 sec[theta]^2 tan[theta]^2]
x = -cot[theta] inside
y = 17.5 + inside
return [x,y]
}
}