2012-01-26 21 views
5

Estoy girando puntos alrededor de un punto central en el espacio 2D. Los puntos son el punto central, la posición del mouse anterior y la nueva posición del mouse. Mi función de rotación funciona bien, y puedo calcular el ángulo perfectamente. Pero quiero calcular un ángulo negativo si el usuario mueve su mouse en una dirección que debe interpretarse como en sentido antihorario.Recuperar un ángulo positivo o negativo de 3 puntos

Por ejemplo, moviendo el mouse hacia la derecha (eje x positivo) debería girar hacia la derecha si está por encima (menor que) el valor y del centro, pero debería girar en sentido antihorario si está realmente debajo (mayor que) el valor y del punto central.

Esto es lo que tengo:

PointF centerPoint; 
PointF oldPoint; 
PointF newPoint; 

double Xc = centerPoint.X; 
double Yc = centerPoint.Y; 
double Xb = oldPoint.X; 
double Yb = oldPoint.Y; 
double Xa = newPoint.X; 
double Ya = newPoint.Y; 

double c2 = (Math.Pow(Xb - Xa, 2) + Math.Pow(Yb - Ya, 2)); 
double a2 = (Math.Pow(Xb - Xc, 2) + Math.Pow(Yb - Yc, 2)); 
double b2 = (Math.Pow(Xa - Xc, 2) + Math.Pow(Ya - Yc, 2)); 

double a = Math.Sqrt(a2); 
double b = Math.Sqrt(b2); 

double val = (a2 + b2 - c2)/(2 * a * b); 
double angle = Math.Acos(val); 

así que necesito una manera de hacer ángulo negativo cuando tiene que ser, por lo que los puntos de girar hacia la derecha o hacia la izquierda para seguir la posición del ratón.

Respuesta

7

Prueba de esto, pero no estoy seguro:

double v1x = Xb - Xc; 
double v1y = Yb - Yc; 
double v2x = Xa - Xc; 
double v2y = Ya - Yc; 

double angle = Math.Atan2(v1x, v1y) - Math.Atan2(v2x, v2y); 
+0

Esto parece funcionar. Va en sentido contrario a las agujas del reloj cuando se supone que debe hacerlo. –

0

Parece que todo lo que tiene que hacer es

angle = angle > Math.PI ? angle - 2*Math.PI : angle; 

al final de su código. Esto le dará una rotación en el sentido de las agujas del reloj a la derecha de la línea definida por centerPoint y oldPoint, y en sentido contrario a las agujas del reloj a la izquierda, independientemente de la orientación.

+0

ángulo nunca es mayor que Math.PI. –

+0

Hmmm. Es posible que necesite reformular su cálculo de ángulo para utilizar Math.atan2(), de modo que obtenga un ángulo en el cuadrante correcto. –

0

Dados los vectores (x1, y1) y (x2, y2), sugeriría calcular el producto cruzado y el producto escalar, y luego usar Atan2() sobre ellos. Eso funcionará en todos los casos en que ambos vectores sean distintos de cero y las longitudes de vector sean "razonables".

3
private double AngleFrom3PointsInDegrees(double x1, double y1, double x2, double y2, double x3, double y3) 
{ 
    double a = x2 - x1; 
    double b = y2 - y1; 
    double c = x3 - x2; 
    double d = y3 - y2; 

    double atanA = Math.Atan2(a, b); 
    double atanB = Math.Atan2(c, d); 

    return (atanA - atanB) * (-180/Math.PI); 
    // if Second line is counterclockwise from 1st line angle is 
    // positive, else negative 
} 
+0

tuve que agregar valores X negativos para que funcione para mí (los cálculos ahora coinciden con AutoCAD) – DarkPh03n1X

Cuestiones relacionadas