tags:

views:

36

answers:

1

I need to draw something like a subway map (multiple routes along the same path) using PHP's image library. Here's an example:

  *********
  ******** *
  ******* * *
         * * *
          * * *
          * * *
          * * *
          * * *                      
          * * *                      
          * * *                      
           * * *                     
            * * *                    
             * * *                   
              * * ********************
               * *********************
                **********************

It's easy enough to draw one line along this path. I don't know how to draw multiple lines that follow the path but have an equal amount of space between them.

+1  A: 

For a given point A, and more lines through it, for the first points you'll have to decide whether points go 'inside'(B) the track, or 'outside'(C):

  ********C
  D******A *
  Q*****B * *
         * * *
          * E *

Now, you can calculate the offset of your point B to point A as a path from with length=offset (5px for instance) along the angle the which is half the clockwise angle between AE & AD for the 'inside' B (or the clockwise angle from AD to AE for the 'outside' C, or just use a negative offset later on). You'll want point B on a distance of 5px from A along the line through A with an angle angle AE + ((angle AD - angle AE) / 2)

I'm by no means a Math wiz, and the only time I needed to calculate angles like those were in javascript, I'll give it as an example, rewrite to PHP as you please (anybody who does know math, feel free to laugh & correct when needed):

var dx = b.x - a.x;
var dy = b.y - a.y;
if(dx == 0 && dy == 0){
    answer = 0;
} else if(dx > 0 && dy >= 0 ){
    answer = Math.atan(dy/dx);
} else if(dx <= 0 && dy > 0){
    answer = Math.atan(dx/dy) + (Math.PI * 0.5);
} else if(dx <= 0 && dy <= 0){
    answer = Math.atan(dy/dx) + Math.PI;
} else if(dx >= 0 && dy <= 0){
    answer = Math.atan(dy/dx) + (Math.PI * 1.5);
}

So, in a grid where D=(0,10),A=(10,10), E=(20,20):

  • The angle through AE = 45° (PI/4 rad),through AD = 180° (PI rad)
  • The angle through AB is then (45 + ((180-45)/2))=> 112.5° (5/8 PI rad)
  • 5px offset from A=(10,10) through angle 112.5° gives you this location for B:
    • Bx = Ax + (cos(angle) * 5) = +/- 8.1
    • By = Ay + (sin(angle) * 5) = +/- 14.6
  • At the 'sibling' point Q next to starting point D you have no previous path to reference / calculate an angle from, so I'd take the perpendicular: angle DQ = angle DA + 90° (PI/2 rad) (in the example you could just do Dy+5, but maybe you don't always start parallel to one of the 2 axis)
  • Rinse and repeat for all other points, draw lines between the calculated coordinates.
Wrikken