计算两条线之间的角度而不必计算斜率? (JAVA)

时间:2010-07-29 17:06:15

标签: java math geometry coordinates trigonometry

我有两条线:L1和L2。我想计算两条线之间的角度。 L1有点:{(x1, y1), (x2, y2)},L2有点:{(x3, y3), (x4, y4)}

如何计算这两条线之间形成的角度,而无需计算斜率?我目前遇到的问题是,有时我有水平线(沿x轴的线),下面的公式失败(除以零例外):

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

其中m1m2分别是第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 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:13)

在这种情况下,Dot产品可能更有用。 Here您可以找到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;
}
祝你好运!

答案 2 :(得分: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个向量的点积等于角度时间的余弦值,两个向量的长度。这会计算点积,除以向量的长度,并使用反余弦函数来恢复角度。

答案 3 :(得分: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;
}

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

您可以结帐我的utility class here

答案 4 :(得分:3)

获取角度的公式为tan a = (slope1-slope2)/(1+slope1*slope2)

您正在使用:

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

所以它应该是:

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

答案 5 :(得分:0)

首先,您确定括号的顺序是否合适?我认为(可能是错的)它应该是这样的:

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

第二,你可以用零做两件事:你可以抓住异常并处理它

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

答案 6 :(得分:0)

检查此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)

答案 7 :(得分:0)

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