У меня есть две Строки: 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;
}
Спасибо.
Точечное произведение, вероятно, более полезно в этом случае. Здесь вы можете найти пакет геометрии для 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;
}
Удачи!
Во-первых, вы уверены, что скобки расположены в правильном порядке? Я думаю (может ошибаться) это должно быть так:
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;
}
Функция 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;
}
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));
Скалярное произведение двух векторов равно косинусу угла, равного длине обоих векторов. Это вычисляет скалярное произведение, делит на длину векторов и использует функцию обратного косинуса для восстановления угла.