计算两条线之间的角度而不需要计算斜率? (爪哇)

发布于 2024-09-12 04:58:01 字数 795 浏览 11 评论 0原文

我有两条线: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;
}

谢谢。

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

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

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

绝影如岚 2024-09-19 04:58:01

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

The atan2 function eases the pain of dealing with atan.

It is declared as double atan2(double y, double x) and converts rectangular coordinates (x,y) to the angle theta from the polar coordinates (r,theta)

So I'd rewrite your code as

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;
}
月亮邮递员 2024-09-19 04:58:01

在这种情况下,点积可能更有用。 在这里您可以找到一个 Java 几何包,它提供了一些有用的帮助器。下面是他们用于确定两个 3-d 点之间角度的计算。希望它能让您开始:

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

祝您好运!

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

Good luck!

述情 2024-09-19 04:58:01
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));

两个向量的点积等于角度的余弦乘以两个向量的长度。这将计算点积,除以向量的长度,并使用反余弦函数来恢复角度。

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

The dot product of 2 vectors is equal to the cosine of the angle time the length of both vectors. This computes the dot product, divides by the length of the vectors and uses the inverse cosine function to recover the angle.

煮酒 2024-09-19 04:58:01

也许我的 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 <= x < 360

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

Maybe my approach for Android coordinates system will be useful for someone (used Android PointF class to store points)

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

It return positive value in degrees for any quadrant: 0 <= x < 360

You can checkout my utility class here

一城柳絮吹成雪 2024-09-19 04:58:01

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

您正在使用:

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

所以它应该是:

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

The formula for getting the angle is tan a = (slope1-slope2)/(1+slope1*slope2)

You are using:

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

So it should be:

double angle = Math.atan((slope1 - slope2) / (1 + slope1 * slope2));
情话墙 2024-09-19 04:58:01

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

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

First, are you sure the brackets are in the right order? I think (could be wrong) it should be this:

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

Second, there are two things you could do for the div by zero: you could catch the exception and handle it

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

...or you could check that your divisors are never zero before you attempt the operation.

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;
 }
行至春深 2024-09-19 04:58:01

检查这个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)

Check this Python code:

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)
悲凉≈ 2024-09-19 04:58:01
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)))
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)))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文