Вычисление угла между двумя строками, не имея необходимость вычислять наклон? (Java)

У меня есть две Строки: 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;
}

Спасибо.

33
задан Hannele 11 April 2015 в 20:56
поделиться

4 ответа

Точечное произведение, вероятно, более полезно в этом случае. Здесь вы можете найти пакет геометрии для 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;
}

Удачи!

13
ответ дан 27 November 2019 в 17:24
поделиться

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

   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;
 }
0
ответ дан 27 November 2019 в 17:24
поделиться

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

Он объявлен как double atan2 (double y, double x) и преобразует прямоугольные координаты (x, y) в угол тета от полярного координаты (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;
}
95
ответ дан 27 November 2019 в 17:24
поделиться
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));

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

10
ответ дан 27 November 2019 в 17:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: