Creating a TRK Pt I by P.A.Flack 1999
contact: phil@flack99.freeserve.co.uk
                                                                                                             last revised 7/August/1999

Hopefully, if you follow the instructions on this page, you will be able to create a new .trk file for the track of your choice.  The method described is not the only way to get the required numbers, but in my opinion it is the most accurate, and will result in the start and end points matching up every time (good news).  For the trk I used this method for, the start and end points were within 0.0001metres - not too bad...

Some points to consider:

Stage I

Get a rough plan of the track drawn out with as many measurements as you can do on it.  Typically, you'll need:



This diagram shows 3 straights.  The only coordinates you should know, are two (x,y) pairs for each straight (R points).  These are the points that will be used to calculate everything else, and the precision of these is not too important.  It is probably easier to measure them to the closest metre, for example.

First calculations:  The I points (intersections of each pair of straights).  Since you know the equations of the straights (from the two points per straight), the I points can be found.  Here's some code that'll do the job:  You may as well use the final case for all the calculations you do by 'hand'.

int calcintersection(double& ix, double& iy, double ax1, double ay1, double ax2, double ay2, double bx1, double by1, double bx2, double by2) {
   //* calculates the intersection of two lines
   //* all values are doubles to increase the accuracy
   //* parallel lines will fail (-1) (ix=0, iy=0)
   //* single points will fail (-2)  (ix=0, iy=0)
   //* success returns 0
   double adx=ax2-ax1, ady=ay2-ay1;
   double bdx=bx2-bx1, bdy=by2-by1;
   if (adx==0 && ady==0) { ix=0; iy=0; return -2; }    //can't do
   if (bdx==0 && bdy==0) { ix=0; iy=0; return -2; }    //can't do
   if (ady!=0 && bdy!=0) {
        if (adx/ady==bdx/bdy) { ix=0; iy=0; return -1; }    //can't do
   }
        if (adx!=0 && bdx!=0) {
        if (ady/adx==bdy/bdx) { ix=0; iy=0; return -1; }    //can't do
   }
   if (adx==0 && ady!=0 && bdx!=0 && bdy==0) {
        //a is vertical and b is horizontal
        ix=ax1; iy=by1;
        return 1;
   }
   if (ady==0 && adx!=0 && bdy!=0 && bdx==0) {
        //b is vertical and a is horizontal
        ix=bx1; iy=ay1;
        return 1;
   }
   if (ady==0 && adx!=0) {
        //a is horizontal and b is at an angle
        iy=ay1;
        ix=((iy-by1)*(bx2-bx1)/(by2-by1))+bx1;
        return 1;
   }
   if (adx==0 && ady!=0) {
        //a is vertical and b is at an angle
        ix=ax1;
        iy=((ix-bx1)*(by2-by1)/(bx2-bx1))+by1;
        return 1;
   }
   if (bdy==0 && bdx!=0) {
        //b is horizontal and a is at an angle
        iy=by1;
        ix=((iy-ay1)*(ax2-ax1)/(ay2-ay1))+ax1;
        return 1;
   }
   if (bdx==0 && bdy!=0) {
        //b is vertical and a is at an angle
        ix=bx1;
        iy=((ix-ax1)*(ay2-ay1)/(ax2-ax1))+ay1;
        return 1;
   }
   //otherwise all other combinations must be two lines at angles, not parallel, nor single points.  this should work since the cases where ady=0 or bdy=0 have been dealt with and so has (adx/ady - bdx/bdy)=0 (parallel lines)

   iy=(bx1-ax1+(ay1*adx/ady)-(by1*bdx/bdy))/((adx/ady)-(bdx/bdy));
   ix=((iy-ay1)*adx/ady)+ax1;
   return 1;
}

So now you know the lengths between the I & R points ( L = sqrt(  ((x2-x1)*(x2-x1)) + ((y2-y1)*(y2-y1))  )
The angles inside the corners can also be found using the wonderful cosine rule:

angle = acos ( (a^2 - b^2 - c^2) / (-2 * b * c) )    ( or:  cos angle = ((a^2 - b^2 - c^2) / (-2 * b * c))    )

where a,b&c are the lengths.  It doesn't matter how long each is, so using the I point & the two inner R points is the best idea.

So now you know the angle of the corner.  The next stage is...

Stage II
Decide on the radius of each corner.  This might be anything from 5 metres to 500 metres, depending on the sweepyness (made that word up) of the corner.  E.g. La Source would be small radius, Curva Grande medium, and that bit between the 2nd and 3rd corners at Silverstone high (didn't know that bit was curved?  he he).  See the diagram below:

Right then.  (Cx,Cy) is our goal here, the centre of the corner.  Also, SL is a useful value, because it lets you work out the length of the straights (another goal).

SL = r / tan (0.5*alpha),   r = radius of corner

BL = r / sin (0.5*alpha)

Then, using the I point, BL, and alpha in relation to the angle of one of the segments (carry a starting known value right around the track), (Cx, Cy) can be found using simple trig.:     Cx = Ix + cos (a) *BL,   Cy = Iy + sin (a) * BL.

[Hang about, shouldn't we be using a/2 ?  mmm...]

Beta = 180 - alpha.  Beta is the curvature value needed for each corner.

The length of the corner, as the car travels is:  (theta*pi*radius)/180, where theta is the angle opposite alpha, theta=180-alpha.


Phew!

All of that should give you a big bunch of numbers on your nice pretty hand-drawn plan of the track you're creating.  For each straight section, you should have:

For each curve section you should have: Next time I get around to writing something, I'll detail how to make the walls for the .TRK, i.e. the barriers, and different surfaces.  Just look back at the detail above and remember that all that was just to get a centre line.  Eek!


contact: phil@flack99.freeserve.co.uk
last updated: 7/August/1999