i have to find angle ∠BAC in triangle ABC with given coordinates. I'm trying to find cos, then use function acos(cos) and get degrees(not radian) anwser. The input is Ax,Ay,Bx,By,Cx,Cy coordinates
#include <math.h>
int main(){
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n;
int ax,ay,bx,by,cx,cy;
scanf("%d",&n);
for(int i = 0; i<n; i ){
scanf("%d %d %d %d %d %d",&ax,&ay,&bx,&by,&cx,&cy);
double cosab = (ax*bx ay*by)/ (sqrt(ax*ax ay*ay)* sqrt(bx*bx by*by));
cosab =180* acos(cosab)/M_PI;
printf("cosab is %0.20g\n",cosab);
}
return 0;
}
With input
8
2 1 2 3 5 5
2 1 4 3 2 3
3 1 3 5 2 3
0 0 1 0 10 0
0 0 1 0 -10 1
7 4 3 3 3 3
0 0 1 0 1 1e-5
0 0 1 0 1e-5 1
I get
cosab is 29.744881296942211
cosab is 10.304846468766044
cosab is 40.601294645004479
cosab is -1.#IND
cosab is -1.#IND
cosab is 15.255118703057764
cosab is -1.#IND
cosab is -1.#IND
But the anwser should be
36.869897645844019962
45
26.565051177077990019
0
174.28940686250035697
0
0.00057295779511172474814
89.999427042204885652
What is "-1.#IND" and what's wrong with my code?
CodePudding user response:
Input is not only integers
1e-5
is like 0.00001
. Read that into a double
.
// int ax,ay,bx,by,cx,cy;
double ax,ay,bx,by,cx,cy;
...
//scanf("%d %d %d %d %d %d",&ax,&ay,&bx,&by,&cx,&cy);
scanf("%lf %lf %lf %lf %lf %lf",&ax,&ay,&bx,&by,&cx,&cy);
Be careful with acos()
The |x|
in acos(x)
may be just a tad larger than 1.0 due to computationally issues. Best to check
// add
if (cosab > 1.0) cosab = 1.0;
else if (cosab < -1.0) cosab = -1.0;
cosab = 180 * acos(cosab) / M_PI;
Perhaps better precision
// sqrt(ax*ax ay*ay)
hypot(ax, ay)
Other issues may exist too
Worth reviewing if proper formula is used: Law of cosines
CodePudding user response:
As others have pointed out, the input coordinates are floating point, so let us read them into double
s:
double ax,ay,bx,by,cx,cy;
/* Read coordinates of A, B, and C. */
scanf("%lf%lf%lf%lf%lf%lf",&ax,&ay,&bx,&by,&cx,&cy);
∠BAC is the angle between lines AB and AC. Let us consider those as vectors AB and AC represented by their x and y components:
/* Convert to vectors AB and AC (as x and y components). */
double abx = bx - ax; /* x component of vector AB */
double aby = by - ay; /* y component of vector AB */
double acx = cx - ax; /* x component of vector AC */
double acy = cy - ay; /* y component of vector AC */
Now there is a nice formula using ATAN2 on the vector components to get the angle of rotation from one 2D vector to another1:
/*
* Get angle of rotation from vector AB to vector AC
* in the range [-M_PI, M_PI].
*/
double rot_ab_ac = atan2(acy*abx - acx*aby, acx*abx acy*aby);
We want the absolute angle, not a signed angle:
/* Convert to absolute angle BAC. */
double bac = fabs(rot_ab_ac);
Finally, we want the angle in degrees, not radians:
/* Convert to degrees. */
double bac_deg = bac * 180.0 / M_PI;
Note: M_PI
is not defined in the C standard, but can be easily defined by a macro if necessary:
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif