Получить положительный или отрицательный угол с 3 баллов - PullRequest
5 голосов
/ 26 января 2012

Я вращаю точки вокруг центральной точки в 2D-пространстве. Точки - это центральная точка, старая позиция мыши и новая позиция мыши. Моя функция поворота работает отлично, и я могу идеально рассчитать угол. Но я хочу вычислить отрицательный угол, если пользователь перемещает свою мышь в направлении, которое следует интерпретировать как против часовой стрелки.

Например, перемещение мыши вправо (положительная ось x) должно вращаться по часовой стрелке, если вы находитесь выше (меньше) значения y центральной точки, но оно должно вращаться против часовой стрелки, если вы на самом деле ниже ( больше чем) значение у центральной точки.

Вот что у меня есть:

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

Поэтому мне нужен способ сделать угол отрицательным, когда это необходимо, чтобы точки вращались по часовой стрелке или против часовой стрелки, чтобы следовать положению мыши.

Ответы [ 4 ]

7 голосов
/ 26 января 2012

Попробуйте, но я не уверен:

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);
3 голосов
/ 18 марта 2013
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 голосов
/ 26 января 2012

Учитывая векторы (x1, y1) и (x2, y2), я бы предложил вычислить перекрестное произведение и произведение точек, а затем использовать Atan2 () для них. Это будет работать во всех случаях, когда оба вектора ненулевые, а длины векторов «разумны».

0 голосов
/ 26 января 2012

Похоже, все, что вам нужно сделать, это

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

в конце вашего кода. Это даст вам вращение по часовой стрелке справа от линии, определенной centerPoint и oldPoint, и против часовой стрелки слева от нее, независимо от ориентации.

...