Lance
Lance

Reputation: 23

Calculating the rotation angle to follow a line in Processing

I have a random line being drawn, and I want to trace along the line with a Letter, V in this case. I would like the bottom point of the V to rotate and follow the direction of the line no matter what angle or direction the line is drawn. But I'm honestly at a loss for how to calculate that angle. Below is some bare bones code to demonstrate my problem. You'll see the Red line being drawn, and I would like the V's bottom point to lead the line being drawn.

Thanks in advance for any suggestions.

float [ ] lineProgress = { 75, 350, 350, 350, 0 };
int lineSpeed = 25;
float angle = 0;

void setup() {
  background (255);
  size(400,400);
  noFill();
  frameRate(5);
}

void draw() 
{
    background (255);
    strokeWeight(1);

    stroke (0,255,0);
    line(lineProgress[0],lineProgress[1],lineProgress[2],lineProgress[3]);

    stroke (255,0,0);

    fill(255, 0,0, 125);

    float angle;
    //How Do I calculate this based on the line being drawn?
    angle =radians(270);

     line(
         lineProgress[0]
         , lineProgress[1]
         , lerp(lineProgress[0], lineProgress[2],lineProgress[4]/lineSpeed)
         , lerp(lineProgress[1], lineProgress[3],lineProgress[4]/lineSpeed)

         );

    rotLetter(
              "V"
               , lerp(lineProgress[0]
               , lineProgress[2]
               , lineProgress[4]/lineSpeed)
               , lerp(lineProgress[1]
               , lineProgress[3],lineProgress[4]/lineSpeed)
               , angle
               ) ;

     rotLetter("V", 200,200,angle) ;               

     lineProgress[4]++;
     if (lineProgress[4]>lineSpeed)
     {
       lineProgress[4]=0;
       lineProgress[0]=random(50,350);
       lineProgress[1]=random(50,350);
       lineProgress[2]=random(50,350);
       lineProgress[3]=random(50,350);
     }

}

void rotLetter(String l, float x, float y, float ang) {
  pushMatrix(); // save state
  textAlign(CENTER); // center letter horiz
  translate(x, y); // move to position
  rotate(ang); // rotate
   // draw char centered on acsender
   // this will work for most Caps, and some lc letters
   // but it will not allways vert center letters
  text(l, 0, textAscent()/2);
  popMatrix(); // return to saved coordinate matrix
}

Upvotes: 2

Views: 2236

Answers (3)

specialscope
specialscope

Reputation: 4218

  1. Find the slope of line y = mx + c (m being the slope). Angle = arctan(m).
  2. Angle to rotate (clockwise) = 2 * Pi - Angle

Upvotes: 1

Alnitak
Alnitak

Reputation: 339816

Given a line from (x0, y0) to (x1, y1) with X offset dx = x1 - x0 and Y offset dy = y1 - y0, the angle is:

atan2(dy, dx)

which will be measured in radians.

Using atan2(y, x) instead of atan(y / x) ensures that the angle returned is in the right quadrant. atan only returns results from -π/2 to +π/2, rather than the full to .

Upvotes: 3

Anders R. Bystrup
Anders R. Bystrup

Reputation: 16060

Your friend in calculating the rotation angle is the sine/cosine relations. You can use any of them, but the tangent one doesn't involve calculating the length of the hypotenuse:

tan A = a / b

so your angle would be

A = arctan( a / b )

or in Java terms:

double angle = Math.atan( ( lineprogress[ 3 ] - lineprogress[ 1 ] ) / 
                          ( lineprogress[ 2 ] - lineprogress[ 0 ] ) );

or as @Alnitak also writes, use atan2 to obtain results in the right quadrant:

double angle =  Math.atan2( lineprogress[ 2 ] - lineprogress[ 0 ] ,
                            lineprogress[ 3 ] - lineprogress[ 1 ] );

assuming that (x1,y1) == ( lineprogress[ 0 ] , lineprogress[ 1 ] ) and congruently for (x2,y2)

Cheers,

Upvotes: 0

Related Questions