Вычислить угол между двумя линиями без необходимости вычислять наклон? (Джава) - PullRequest
33 голосов
/ 29 июля 2010

У меня есть две линии: L1 и L2.Я хочу рассчитать угол между двумя линиями.У L1 есть точки: {(x1, y1), (x2, y2)}, а у L2 есть точки: {(x3, y3), (x4, y4)}.

Как можно рассчитать угол, образованный между этими двумя линиями, без необходимости вычислять наклоны?Проблема, с которой я сталкиваюсь в настоящее время, заключается в том, что иногда у меня появляются горизонтальные линии (линии вдоль оси x), и следующая формула не выполняется (делится на исключение нуля):

arctan((m1 - m2) / (1 - (m1 * m2)))

, где m1 и m2являются наклонами линии 1 и линии 2 соответственно.Существует ли формула / алгоритм, который может вычислять углы между двумя линиями, не получая исключения деления на ноль?Любая помощь будет принята с благодарностью.

Это мой фрагмент кода:

// Calculates the angle formed between two lines
public static double angleBetween2Lines(Line2D line1, Line2D line2)
{
    double slope1 = line1.getY1() - line1.getY2() / line1.getX1() - line1.getX2();
    double slope2 = line2.getY1() - line2.getY2() / line2.getX1() - line2.getX2();
    double angle = Math.atan((slope1 - slope2) / (1 - (slope1 * slope2)));
    return angle;
}

Спасибо.

Ответы [ 8 ]

95 голосов
/ 30 июля 2010

Функция atan2 облегчает работу с atan.

Она объявлена ​​как double atan2(double y, double x) и преобразовывает прямоугольные координаты (x,y) в угол theta из полярных координат (r,theta)

Так что я бы переписал твой код как

public static double angleBetween2Lines(Line2D line1, Line2D line2)
{
    double angle1 = Math.atan2(line1.getY1() - line1.getY2(),
                               line1.getX1() - line1.getX2());
    double angle2 = Math.atan2(line2.getY1() - line2.getY2(),
                               line2.getX1() - line2.getX2());
    return angle1-angle2;
}
13 голосов
/ 29 июля 2010

Точечный продукт, вероятно, более полезен в этом случае. Здесь вы можете найти геометрический пакет для Java, который предоставляет несколько полезных помощников. Ниже приведен их расчет для определения угла между двумя трехмерными точками. Надеюсь, это поможет вам начать:

public static double computeAngle (double[] p0, double[] p1, double[] p2)
{
  double[] v0 = Geometry.createVector (p0, p1);
  double[] v1 = Geometry.createVector (p0, p2);

  double dotProduct = Geometry.computeDotProduct (v0, v1);

  double length1 = Geometry.length (v0);
  double length2 = Geometry.length (v1);

  double denominator = length1 * length2;

  double product = denominator != 0.0 ? dotProduct / denominator : 0.0;

  double angle = Math.acos (product);

  return angle;
}

Удачи!

10 голосов
/ 30 июля 2010
dx1 = x2-x1;
dy1 = y2-y1;
dx2 = x4-x3;
dy2 = y4-y3;

d = dx1*dx2 + dy1*dy2;   // dot product of the 2 vectors
l2 = (dx1*dx1+dy1*dy1)*(dx2*dx2+dy2*dy2) // product of the squared lengths

angle = acos(d/sqrt(l2));

Точечное произведение двух векторов равно косинусу угла времени на длину обоих векторов. Это вычисляет скалярное произведение, делит на длину векторов и использует функцию обратного косинуса для восстановления угла.

7 голосов
/ 26 сентября 2016

Возможно, мой подход к системе координат Android будет кому-то полезен (для хранения точек использовался класс Android PointF)

/**
 * Calculate angle between two lines with two given points
 *
 * @param A1 First point first line
 * @param A2 Second point first line
 * @param B1 First point second line
 * @param B2 Second point second line
 * @return Angle between two lines in degrees
 */

public static float angleBetween2Lines(PointF A1, PointF A2, PointF B1, PointF B2) {
    float angle1 = (float) Math.atan2(A2.y - A1.y, A1.x - A2.x);
    float angle2 = (float) Math.atan2(B2.y - B1.y, B1.x - B2.x);
    float calculatedAngle = (float) Math.toDegrees(angle1 - angle2);
    if (calculatedAngle < 0) calculatedAngle += 360;
    return calculatedAngle;
}

Возвращает положительное значение в градусах для любого квадранта: 0 <= x <360 </p>

Вы можете заказать мой служебный класс здесь

3 голосов
/ 06 мая 2012

Формула для получения угла: tan a = (slope1-slope2)/(1+slope1*slope2)

Вы используете:

tan a = (slope1 - slope2) / (1 - slope1 * slope2)

Так должно быть:

double angle = Math.atan((slope1 - slope2) / (1 + slope1 * slope2));
0 голосов
/ 13 января 2019
dx1=x2-x1 ; dy1=y2-y1 ; dx2=x4-x3 ;dy2=y4-y3.

Angle(L1,L2)=pi()/2*((1+sign(dx1))* (1-sign(dy1^2))-(1+sign(dx2))*(1-sign(dy2^2)))
           +pi()/4*((2+sign(dx1))*sign(dy1)-(2+sign(dx2))*sign(dy2))
           +sign(dx1*dy1)*atan((abs(dx1)-abs(dy1))/(abs(dx1)+abs(dy1)))
           -sign(dx2*dy2)*atan((abs(dx2)-abs(dy2))/(abs(dx2)+abs(dy2)))
0 голосов
/ 29 мая 2018

Проверьте этот код Python:

import math
def angle(x1,y1,x2,y2,x3,y3):

  if (x1==x2==x3 or y1==y2==y3):
    return 180
  else:
    dx1 = x2-x1
    dy1 = y2-y1
    dx2 = x3-x2
    dy2 = y3-y2
    if x1==x2:
      a1=90
    else:
      m1=dy1/dx1
      a1=math.degrees(math.atan(m1))
    if x2==x3:
      a2=90
    else:
      m2=dy2/dx2
      a2=math.degrees(math.atan(m2))
    angle = abs(a2-a1)
    return angle

print angle(0,4,0,0,9,-6)
0 голосов
/ 29 июля 2010

Во-первых, вы уверены, что скобки в правильном порядке? Я думаю (может быть неправильно), это должно быть так:

   double slope1 = (line1.getY1() - line1.getY2()) / (line1.getX1() - line1.getX2());
   double slope2 = (line2.getY1() - line2.getY2()) / (line2.getX1() - line2.getX2());

Во-вторых, есть две вещи, которые вы можете сделать для div на ноль: вы можете перехватить исключение и обработать его

double angle;
try
{
    angle = Math.atan((slope1 - slope2) / (1 - (slope1 * slope2)));
catch (DivideByZeroException dbze)
{
    //Do something about it!
}

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

if ((1 - (slope1 * slope2))==0)
{
    return /*something meaningful to avoid the div by zero*/
}
else 
{
    double angle = Math.atan((slope1 - slope2) / (1 - (slope1 * slope2)));
    return angle;
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...