получить угол линии от горизонта
Я хочу знать, как получить угол линии A-B от горизонтальной оси X. Другие вопросы в так делают это только между двумя линиями. Я знаю, что всегда могу нарисовать вторую линию A-C и вычислить, но мне интересно, есть ли более быстрый метод.
EDIT: я очень уверен, что не делаю преждевременную оптимизацию.
6 ответов
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;
}
Если
- угол небольшой,
- вы можете жить с небольшими неточностями, и
- вы можете использовать угол в радианах, а не градусах,
тогда есть быстрое решение: при этих условиях вы можете предположить, что tan(a) = a = atan(a), и, следовательно, просто опустить вызов atan ().
вы также можете использовать arccosine, если ваша строка находится в форме [r_x,r_y]
, где r_x
это изменение в x и r_y
изменение в y.
angle = arccos( r_x/( r_x*r_x + r_y*r_y ) )
это немного более непрозрачно, но это в основном закон продукта dot:
angle = arccos (r . v)
здесь r
и v
оба единичных вектора (векторы длины 1). В нашем случае, v
вектор [1,0]
, а r -
[r_x,r_y] / (r_x^2+r_y^2)
для того, чтобы сделать его единичным вектором.
ось x на самом деле является линией с уравнением
y = 0
таким образом, вы можете использовать решение, которое у вас уже есть.
Если вам нужны все четыре квадранта, 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;
}