At 2/19/03 02:41 AM, spinewall2 wrote:
by the angle of the line do you mean the slope of the line? If so its easy
(x2-x1)
m= -------
(y2-y1)
No, that's not what he wanted. :P He's thinking like creating a circle using the first point as the center, and the distance b/w the 2 points as the radius, then calculating the angle the 2nd point would make relative to the newly created x-axis...
Think "unit circle", 7th or 8th grade geometry.
If the 2nd point is straight to the right of 1st, the angle is 0.
If the 2nd point is right above 1st, it's pi/2 rads or 90 degrees.
If the 2nd point is straight to the left of the 1st, it's pi rads or 180 degrees.
etc etc... if it's in between, use a li'l trig to calculate the angle. Taking rise/run like your slope formula we can find opp/adj for tan... but at 90 and 270 tan is undefined so I think you need to do it case by case for each quadrant. Hmmm lemme try this in C for ya real quick... I'm gonna do it quadrant by quadrant, using arctan (tan^-1) to find the angle b/w the "bottom axis" of the quadrant and the line the 2nd point makes, then adding 90 degrees for each quadrant passed the 1st.
For instance, if we're in 3rd quadrant the "bottom axis" is the negative x-axis, so opposite = the absolute value of the y displacement, and adjacent = absolute value of the x displacement... and we'd add 180 degrees to the arctan of that.
Points on the axis are gonna be handled as special cases...
this is gonna look REALLY ugly with the spacing changed/taken out... :P
email me if ya want the pretty .C file I wrote in wordpad
-------------------------------------------------------
#include <stdio.h>
#include <math.h>
typedef enum{Quad1, Quad2, Quad3, Quad4, x_axis, y_axis, origin} Quad;
//Which Quadrant, Quad1 = 0, Quad2 = 1, etc, and values for axis and pts being same spot
typedef struct COORDINATE { //xy coordinate of pixel on screen
int x;
int y;
} Coor;
double CalcAngle(Coor pt1, Coor pt2);
Quad GetQuad(int dx, int dy);
void main(void)
{
Coor point1, point2;
double angle;
printf("Enter point 1: ");
scanf(" %i %i", &point1.x, &point1.y);
printf("Enter point 2: ", point2.x, point2.y);
scanf(" %i %i", &point2.x, &point2.y);
angle = CalcAngle(point1, point2);
printf("Angle = %g", angle);
return;
}
double CalcAngle(Coor pt1, Coor pt2)
{
int disp_x, disp_y; //displacement in X and Y direction
double angle;
Quad location;
disp_x = pt2.x - pt1.x;
disp_y = pt1.y - pt2.y; //reverse order because of pixel numeric values
location = GetQuad(disp_x, disp_y); //find out where we are
switch(location) {
case origin: angle = 0; break; //angle is undefined, but we return a value of zero
case y_axis:
if(disp_y > 0) angle = 90; //above point 1
else angle = 270; break; //below point 1
case x_axis:
if(disp_x > 0) angle = 0; //to right of point 1
else angle = 180; break; //to left of point 1
case Quad1:
angle = atan2(disp_y, disp_x); //generic case
angle = angle / M_PI * 180; break; //convert from radians to degrees
case Quad2:
angle = atan2(-disp_x, disp_y);
angle = angle / M_PI * 180.0 + 90; break; //"rotate" quadrants to use tan function
case Quad3:
angle = atan2(-disp_y, -disp_x);
angle = angle / M_PI * 180.0 + 90*2; break; //by switching signs of displacements
case Quad4:
angle = atan2(disp_x, -disp_y); //then add 90 degrees for each quad passed 1st
angle = angle / M_PI * 180.0 + 90*3;
}
return angle;
}
Quad GetQuad(int dx, int dy) //finds which quadrant point 2 is in relative to point 1
{ //will check if point 1 = point 2 or in point 2 is on an axis of point 1
if(dx == 0 && dy == 0) return origin;
if(dx == 0) return y_axis;
if(dy == 0) return x_axis;
if(dx > 0 && dy > 0) return Quad1;
if(dx < 0 && dy > 0) return Quad2;
if(dx < 0 && dy < 0) return Quad3;
if(dx > 0 && dy < 0) return Quad4;
}
-------------------------------------------------------
That's one way of doing it. You can simplify it alot with a few utility fuctions and breaking it down to a generic "if(disp_x == 0) angle = 90 + location*90; else angle = atan2(y_disp, x_disp) / M_PI * 180 + location*90" and losing the x_axis/y_axis/origin out of the enumerated type... I was too lazy to spend the extra 5 mins tho heh :P
-Pyro