2012-01-26 7 views
5

I punti di rotazione intorno a un punto centrale nello spazio 2D. I punti sono il punto centrale, la vecchia posizione del mouse e la nuova posizione del mouse. La mia funzione di rotazione funziona bene e posso calcolare perfettamente l'angolo. Ma voglio calcolare un angolo negativo se l'utente sta muovendo il mouse in una direzione che dovrebbe essere interpretata in senso antiorario.Recupera un angolo positivo o negativo da 3 punti

Ad esempio, spostando il mouse verso destra (asse x positivo) dovrebbe ruotare in senso orario se si è sopra (meno del) valore y del punto centrale, ma dovrebbe ruotare in senso antiorario se si è effettivamente al di sotto (maggiore di) il valore y del punto centrale.

Ecco quello che ho:

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); 

Così ho bisogno di un modo per rendere angolo negativo, quando ha bisogno di essere, in modo che i punti di ruotare in senso orario o antiorario per seguire la posizione del mouse.

risposta

7

Prova questo, ma non sono sicuro:

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

Sembra funzionare. Va in senso antiorario quando è previsto. –

0

sembra che tutto quello che dovete fare è

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

alla fine del codice. Questo ti darà una rotazione in senso orario a destra della linea definita da centerPoint e oldPoint, e in senso antiorario a sinistra di esso, indipendentemente dall'orientamento.

+0

angolo è mai superiore Math.PI. –

+0

Hmmm. Potrebbe essere necessario riformulare il calcolo dell'angolo per utilizzare Math.atan2(), in modo da ottenere un angolo nel quadrante corretto. –

0

Dato i vettori (x1, y1) e (x2, y2), suggerirei di calcolare il prodotto incrociato e il prodotto punto e quindi di utilizzare Atan2() su di essi. Ciò funzionerà in tutti i casi in cui entrambi i vettori non sono zero e le lunghezze dei vettori sono "ragionevoli".

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

ho dovuto aggiungere valori X negativi per farlo funzionare per me (i calcoli ora corrispondono ad AutoCAD) – DarkPh03n1X