tangente - Java: calcular el ángulo entre dos puntos en grados
funciones trigonometricas en java (6)
Necesito calcular el ángulo en grados entre dos puntos para mi propia clase de punto, el punto a será el punto central.
Método:
public float getAngle(Point target) {
return (float) Math.toDegrees(Math.atan2(target.x - x, target.y - y));
}
Prueba 1: // devuelve 45
Point a = new Point(0, 0);
System.out.println(a.getAngle(new Point(1, 1)));
Prueba 2: // devuelve -90, esperado: 270
Point a = new Point(0, 0);
System.out.println(a.getAngle(new Point(-1, 0)));
¿Cómo puedo convertir el resultado devuelto en un número entre 0 y 359?
¿Qué tal algo así como:
angle = angle % 360;
Basado en la respuesta de Saad Ahmed , este es un método que puede usarse para dos puntos.
public static double calculateAngle(double x1, double y1, double x2, double y2)
{
double angle = Math.toDegrees(Math.atan2(x2 - x1, y2 - y1));
// Keep angle between 0 and 360
angle = angle + Math.ceil( -angle / 360 ) * 360;
return angle;
}
Comencé con la solución de johncarls, pero necesitaba ajustarla para obtener exactamente lo que necesitaba. Principalmente, necesitaba que girara en el sentido de las agujas del reloj cuando aumentaba el ángulo. También necesitaba 0 grados para apuntar al NORTE. Su solución me acercó, pero decidí publicar mi solución también en caso de que ayude a alguien más.
He agregado algunos comentarios adicionales para ayudar a explicar mi comprensión de la función en caso de que necesite hacer modificaciones simples.
/**
* Calculates the angle from centerPt to targetPt in degrees.
* The return should range from [0,360), rotating CLOCKWISE,
* 0 and 360 degrees represents NORTH,
* 90 degrees represents EAST, etc...
*
* Assumes all points are in the same coordinate space. If they are not,
* you will need to call SwingUtilities.convertPointToScreen or equivalent
* on all arguments before passing them to this function.
*
* @param centerPt Point we are rotating around.
* @param targetPt Point we want to calcuate the angle to.
* @return angle in degrees. This is the angle from centerPt to targetPt.
*/
public static double calcRotationAngleInDegrees(Point centerPt, Point targetPt)
{
// calculate the angle theta from the deltaY and deltaX values
// (atan2 returns radians values from [-PI,PI])
// 0 currently points EAST.
// NOTE: By preserving Y and X param order to atan2, we are expecting
// a CLOCKWISE angle direction.
double theta = Math.atan2(targetPt.y - centerPt.y, targetPt.x - centerPt.x);
// rotate the theta angle clockwise by 90 degrees
// (this makes 0 point NORTH)
// NOTE: adding to an angle rotates it clockwise.
// subtracting would rotate it counter-clockwise
theta += Math.PI/2.0;
// convert from radians to degrees
// this will give you an angle from [0->270],[-180,0]
double angle = Math.toDegrees(theta);
// convert to positive range [0-360)
// since we want to prevent negative angles, adjust them now.
// we can assume that atan2 will not return a negative value
// greater than one partial rotation
if (angle < 0) {
angle += 360;
}
return angle;
}
El javadoc para Math.atan(double) es bastante claro que el valor de retorno puede variar de -pi / 2 a pi / 2. Entonces necesita compensar ese valor de retorno.
podrías agregar lo siguiente:
public float getAngle(Point target) {
float angle = (float) Math.toDegrees(Math.atan2(target.y - y, target.x - x));
if(angle < 0){
angle += 360;
}
return angle;
}
por cierto, ¿por qué no quieres usar un doble aquí?
angle = Math.toDegrees(Math.atan2(target.x - x, target.y - y));
ahora para la orientación de valores circulares para mantener el ángulo entre 0 y 359 puede ser:
angle = angle + Math.ceil( -angle / 360 ) * 360