получить угол линии от горизонта - PullRequest
7 голосов
/ 01 июля 2010

Я хочу знать, как получить угол линии AB от горизонтальной оси X. Другие вопросы в SO делают это только между двумя линиями.Я знаю, что всегда могу нарисовать вторую линию AC и рассчитать, но мне интересно, есть ли более быстрый метод.

РЕДАКТИРОВАТЬ: Я уверен, что я не делаю преждевременной оптимизации.

Ответы [ 6 ]

10 голосов
/ 01 июля 2010

Вы можете использовать atan для этого.

angle = atan((By-Ay)/(Bx-Ax))
8 голосов
/ 13 июля 2011
    private double Angulo(int x1, int y1, int x2, int y2)
    {
        double degrees;

        // Avoid divide by zero run values.
        if (x2 - x1 == 0)
        {
            if (y2 > y1)
                degrees = 90;
            else
                degrees = 270;
        }
        else
        {
            // Calculate angle from offset.
            double riseoverrun = (double)(y2 - y1) / (double)(x2 - x1);
            double radians = Math.Atan(riseoverrun);
            degrees = radians * ((double)180 / Math.PI);

            // Handle quadrant specific transformations.       
            if ((x2 - x1) < 0 || (y2 - y1) < 0)
                degrees += 180;
            if ((x2 - x1) > 0 && (y2 - y1) < 0)
                degrees -= 180;
            if (degrees < 0)
                degrees += 360;
        }
        return degrees;
    }
1 голос
/ 01 июля 2010

Вы также можете использовать арккозин, если ваша строка имеет вид [r_x,r_y], где r_x - это изменение x, а r_y - это изменение y.

angle = arccos( r_x/( r_x*r_x + r_y*r_y ) )

Это немного более непрозрачно, но в основном это закон точечного произведения:

angle = arccos (r . v)

, где r и v оба - единичные векторы (векторы длины 1).В нашем случае v - это вектор [1,0], а r -

[r_x,r_y] / (r_x^2+r_y^2)

, чтобы сделать его единичным вектором.

1 голос
/ 01 июля 2010

Если

  1. Угол небольшой,
  2. Вы можете жить с небольшими неточностями, а
  3. Вы можете использовать угол в радианах, а не в градусах,

тогда есть быстрое решение: в этих условиях можно предположить, что tan (a) = a = atan (a), и, следовательно, просто пропустить вызов atan ().

0 голосов
/ 18 декабря 2011

Если вам нужны все четыре квадранта, Atan2 больше подходит, чем Atan.

public static int GetAngleBetweenPoints(PointF pt1, PointF pt2)
{
    float dx = pt2.X - pt1.X;
    float dy = pt2.Y - pt1.Y;

    int deg = Convert.ToInt32(Math.Atan2(dy, dx) * (180 / Math.PI));
    if (deg < 0) { deg += 360; }

    return deg;
}
0 голосов
/ 01 июля 2010

Ось X на самом деле является линией с уравнением

y = 0

чтобы вы могли использовать решение, которое у вас уже есть.

...