Imagine I have drawn a circle with center coordinates (cx,cy) on the screen and a random point (A) is selected on the circle.
By having the the coordinates of point A, I need to find the angle of (a).
Update:
I have tried using the following formula:
Math.toDegrees(Math.asin(((x - cx) / radius).toDouble()))
which is actually the reverse of (the circle is created by feeding angles to this one):
x = radius * Math.sin(Math.toRadians(angle.toDouble())) + cx
y = radius * Math.cos(Math.toRadians(angle.toDouble())) + cy
But since the y coordinate is not present in the formula the answer could be wrong.
If you know the cartesian coordinates of the point A(x,y), then you can find the angle theta by converting it into polar coordinates as below:
double theta = Math.toDegrees(Math.atan2(y - cy, x - cx));
This formula works if your X axis is in 0 degrees, otherwise you need to consider the offset.
I think the method you are looking for i Math.atan2 which computes the angle to an x and y cordinate. I have now modified the code to adjust for putting 0 degrees downwards. I have also flipped the y-axis to put 0, 0 cordinate in the upper left corner (screen coordinates), and adjusted degrees above 180 to be reported as negative degrees:
public double theta(int cx, int cy, int x, int y)
{
double angle = Math.toDegrees(Math.atan2(cy - y, x - cx)) + 90;
return angle <= 180? angle: angle - 360;
}
A small test to verify some angles...
@Test
public void test()
{
assertThat(theta(50, 50, 60, 50), is(90.0));
assertThat(theta(50, 50, 50, 60), is(0.0));
assertThat(theta(50, 50, 40, 50), is(-90.0));
assertThat(theta(50, 50, 50, 40), is(180.0));
}
You can find the tangent angles and add to 90 or substruct from 270 that angle and find the result, I believe. I design the code like your drawing. You can make it more generic, I guess. You have 4 area:
Code:
public static double findAngle(double x, double y,
double cx, double cy, double radius){
double beta, alfa;
double distanceX = Math.abs(Math.abs(x) - Math.abs(cx));
double distanceY = Math.abs(Math.abs(y) - Math.abs(cy));
// check the point is on the circle or not
// with euchlid
if (radius != Math.sqrt(x * x + y * y)) {
return -1;
}
if (x >= cx && y <= cy) {
// find tangent
beta = Math.atan(distanceY / distanceX);
alfa = 90 - beta;
return alfa;
}
// 90-180 -> second area
else if (x >= cx && y >= cy) {
beta = Math.atan(distanceY / distanceX);
alfa = 90 + beta;
return alfa;
}
// 180 - -90 -> third area
else if (x <= cx && y >= cy) {
beta = Math.atan(distanceY / distanceX);
alfa = 270 - beta;
return alfa;
}
// -90 - 0 -> forth area
else if (x <= cx && y <= cy) {
beta = Math.atan(distanceY / distanceX);
alfa = 270 + beta;
if (alfa == 360) {
alfa = 0;
}
return alfa;
}
else {
return -1;
}
}
The main catch with Atan2
is the center point. If your center is offset (Cx, Cy)
and not at the origin and you want to find the arc angle between (X1, Y1)
and (X2, Y2)
then I would suggest this approach:
double startAngle = Math.Atan2(Y1-Cy, X1-Cx);
double endAngle = Math.Atan2(Y2-Cy, X2-Cx);
double ArcAngle = endangle - startAngle;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With