Reputation: 894
Atan2(y,x) will return a float between -pi and pi. I want to calculate the distance between two angles, but the non-continuity is throwing me off.
See this for better understanding.
I want to be able to calculate the distance between Angle 1 and Angle 2.
The whole point of this is to be able to create a cone from the center to a specified angle. Essentially I will be evaluating:
if(DistanceFromAngle1 < pi/4 [45°])
{
Angle2 is part of cone
}
Upvotes: 4
Views: 7220
Reputation: 11
Two wariants of angle difference calculation:
procedure TForm1.sButton1Click(Sender: TObject);
Var a, b, dif : Extended;
begin
a := sCalcEdit1.Value;
b := sCalcEdit2.Value;
If ((a < 180) and (b >= 180) or
(a >= 180) and (b < 180)) and (abs(a - b) < 180) then
Begin
End else
If (a < 180) and (b >= 180) then
Begin
b := b - 360;
End else
If ((a >= 180) and (b < 180)) then
Begin
a := a - 360;
End;
dif := abs(a - b);
sCalcEdit3.Value := dif;
end;
procedure TForm1.sButton2Click(Sender: TObject);
Var a, b, dif : Extended;
begin
a := sCalcEdit1.Value * pi / 180;
b := sCalcEdit2.Value * pi / 180;
dif := arccos(cos(a - b));
sCalcEdit3.Value := dif * 180 / pi;
end;
Upvotes: 1
Reputation: 10127
If by distance you mean the straight line joining the two interception points, you can calculate the distance by doing this:
SQRT( ( ABS|cos(A) - cos(B)| )^2 + ( ABS|sin(A) - sin(B)| )^2 )
SQRT = square root
ABS = Absolute value
If the distance is the angle, you calculate it by doing (pseudo-code)
var angle = ABS(A - B)
if(angle > pi) angle = 2*pi - angle
return angle
Upvotes: 7
Reputation: 33738
dAngle1 = //convert angle1 to degrees
dAngle2 = // convert to degrees
delta = Math.Max(dAngle1, dAngle2) - Math.Min(dAngle1, dAngle2)
if (180 < delta) {
delta = 360 - delta;
}
// convert delta to radians if you want
Upvotes: 5
Reputation: 21793
EDIT: I'm not sure if this will work. I translated it from some python code, but I'm not sure if divmod(radians, math.pi*2)[1]
is the same behaviour as System.Math.IEEERemainder(radians, Math.PI*2.0)
. Need to test...
EDIT2: I think using % is correct
EDIT3: Blah, it's not correct because it returns a negative value for negative numbers. Does anyone know how to get python divmod in C#?
How to calculate the angle between two angles:
public static double NormalizeAngle(double radians)
{
return fmod(radians,Math.PI*2.0); # this method doesn't exist, see above
}
public static double ArcLength(double radians1, double radians2)
{
radians1 = NormalizeAngle(radians1);
radians2 = NormalizeAngle(radians2);
return Math.Min(NormalizeAngle(radians1 - radians2, NormalizeAngle(radians2 - radians1));
}
How it works is it tries both ways around, all calculations mod 2pi, and it picks the one with a smaller distance.
Upvotes: 0
Reputation: 186
π/2 is 90°, not 45°. I'm going to assume you want to know whether Angle 2 is in an interval centered around Angle 1 which extends 45° away from it in both directions.
You can take the difference between Angle 2 and Angle 1, and reduce modulo 2π until the difference is in [-π, π). This will give a signed distance between Angle 2 and Angle 1. Then, check to see if this is in (-π/4, π/4). Since the value returned by atan2 is always between -π and π, the original difference will always be between -2π and 2π, so you can lump all this into one check:
if (angle2 - angle1 < -7π/4 ||
(angle2 - angle1 > -π/4 && angle2 - angle1 < π/4) ||
angle2 - angle1 > 7π/4)
{
angle2 is less than 45° away from angle1
}
Upvotes: 1
Reputation: 3226
I want to give an alternative solution: You can use vector math. This can for example be useful if you have two vectors as a starting point (which seems to be your case).
Given two normalized vectors, a
and b
, the angle between them simply becomes acos(dot(a, b)) = acos(ax*bx + ay*by)
.
To get a normalized vector from an angle, alpha
, you can use a = vec2(cos(alpha), sin(alpha))
, for example.
To normalize a denormal vector, use na = a / length(a) = a / sqrt(dot(a, a))
.
Upvotes: 0