Derby.frink

Download or view Derby.frink in plain text format


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


Download or view Derby.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 19944 days, 14 hours, 12 minutes ago.