Calculating the angle between two lines without having to calculate the slope? (Java)

jNo*_*oob 33 java math geometry trigonometry coordinates

I have two Lines: L1 and L2. I want to calculate the angle between the two lines. L1 has points: {(x1, y1), (x2, y2)} and L2 has points: {(x3, y3), (x4, y4)}.

How can I calculate the angle formed between these two lines, without having to calculate the slopes? The problem I am currently having is that sometimes I have horizontal lines (lines along the x-axis) and the following formula fails (divide by zero exception):

arctan((m1 - m2) / (1 - (m1 * m2)))
Run Code Online (Sandbox Code Playgroud)

where m1 and m2 are the slopes of line 1 and line 2 respectively. Is there a formula/algorithm that can calculate the angles between the two lines without ever getting divide-by-zero exceptions? Any help would be highly appreciated.

This is my code snippet:

// 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;
}
Run Code Online (Sandbox Code Playgroud)

Thanks.

bra*_*jam 95

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 我将'return angle1-angle2;`替换为`返回Math.abs(angle1) - Math.abs(angle2);`你的版本在右下象限中产生错误的结果.Upvoted仍然:) (7认同)
  • @ URL87我有同样的问题,通过反复试验确定它计算弧度. (2认同)
  • 在我的情况下,我不得不使用`return Math.abs(angle1) - Math.abs(angle2)`.也许其他情况可能会有所不同. (2认同)

Jos*_*man 13

Dot product is probably more useful in this case. Here you can find a geometry package for Java which provides some useful helpers. Below is their calculation for determining the angle between two 3-d points. Hopefully it will get you started:

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;
}
Run Code Online (Sandbox Code Playgroud)

Good luck!

  • 是的,点产品将是要走的路,除了不创建一个线的矢量形式(你需要做点积)基本上涉及获得斜率? (2认同)

phk*_*ler 10

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

2个矢量的点积等于角度时间的余弦值,两个矢量的长度.这会计算点积,除以矢量的长度,并使用反余弦函数来恢复角度.


Deh*_*imb 7

也许我对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;
}
Run Code Online (Sandbox Code Playgroud)

对于任何象限,它以度为单位返回正值:0 <= x <360

你可以在这里查看我的实用程序类


Fru*_*ner 0

首先,你确定括号的顺序正确吗?我认为(可能是错的)应该是这样的:

   double slope1 = (line1.getY1() - line1.getY2()) / (line1.getX1() - line1.getX2());
   double slope2 = (line2.getY1() - line2.getY2()) / (line2.getX1() - line2.getX2());
Run Code Online (Sandbox Code Playgroud)

其次,您可以对 div 为零做两件事:您可以捕获异常并处理它

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

...或者您可以在尝试操作之前检查您的除数是否不为零。

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;
 }
Run Code Online (Sandbox Code Playgroud)