Derby.frink

View or download 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]
   }
}


View or download 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 17651 days, 5 hours, 13 minutes ago.