Вычисление угла между двумя линиями без вычисления наклона? (Ява)

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

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

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

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

Это мой fragment кода:

 // 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; } 

Благодарю.

    7 Solutions collect form web for “Вычисление угла между двумя линиями без вычисления наклона? (Ява)”

    Функция 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; } 

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

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

    Удачи!

     dx1 = x2-x1;
     dy1 = y2-y1;
     dx2 = x4-x3;
     dy2 = y4-y3;
    
     d = dx1 * dx2 + dy1 * dy2;  // точечный продукт двух векторов
     l2 = (dx1 * dx1 + dy1 * dy1) * (dx2 * dx2 + dy2 * dy2) // произведение квадратов длины
    
     угол = acos (d / sqrt (l2));
    

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

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

     /** * 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; } 

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

    Вы можете проверить мой class утилиты здесь

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

    Ты используешь:

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

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

     double angle = Math.atan((slope1 - slope2) / (1 + slope1 * slope2)); 

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

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

    Проверьте этот код 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) 
    Interesting Posts

    Как записывать и воспроизводить http-взаимодействия?

    В чем разница между И в Java Generics?

    Остановите элемент панели задач Windows XP навсегда

    Буквенно-цифровая сортировка с использованием LINQ

    Можете ли вы включить / выключить функциональные клавиши с помощью сочетания клавиш на OSX?

    Использование Mockito с несколькими вызовами одного и того же метода с теми же аргументами

    Spring + Hibernate: другой объект с тем же значением идентификатора уже был связан с сеансом

    Что такое интерфейс IUserSecurityStampStore ASP.NET Identity?

    fuken устаревшее предупреждение

    Удаление вызова журнала с помощью proguard

    Получить URI изображения, хранящегося в чертеже

    Программно изменить внешний вид TableView

    Java – чтение, управление и запись WAV-файлов

    Поддерживает ли Windows7 символические ссылки («быстрые клавиши»)?

    Инструмент для размещения текста на обоях рабочего стола

    Давайте будем гением компьютера.