【问题标题】:Calculate which side of a point another point is on计算另一个点在一个点的哪一侧
【发布时间】:2021-09-21 15:18:28
【问题描述】:

我需要计算另一个点在一个点的哪一侧,我一直在谷歌搜索,但我完全不知道所有这些数学方程式的含义,也不知道它们如何更具体地转换为代码或 JavaScript。

我有以下信息:

  • A 点:x、y 和角度(该点将要到达的方向,顺时针向北)
  • B 点:x 和 y

现在我如何知道 B 点在 A 点的左侧还是右侧?非常感谢 JavaScript 中的答案。

【问题讨论】:

  • 点本身没有角度。角度代表什么?
  • 什么是点的“角度”?
  • 角度表示点移动的方向(0-360)
  • @jimmone 您需要与该运动矢量相关的“左或右”信息吗?那么你的 A 点就不是一个点,它通过指定一个点和方向来代表一条线。
  • 顺时针北向

标签: javascript math


【解决方案1】:

考虑表达式的符号(如果angle 以度为单位,则乘以Math.PI/180 得到弧度)

cross = (B.x - A.x)*Math.sin(angle)-(B.y - A.y)*Math.cos(angle)

编辑:对于坐标系OX北,顺时针需要交换cossin

cross = (B.x - A.x)*Math.cos(angle)-(B.y - A.y)*Math.sin(angle)

右侧为正值,左侧为负值(反之亦然,具体取决于您的坐标系方向)

【讨论】:

  • 我尝试了以下操作:A.x = 10,A.y = 10,A.angle = 180 和 B.x = 5,B.y = 5 我得到 cross = -5,这是左边。如果我改变 B.y = 15 我得到 cross = 5,这是正确的,但我认为这是不正确的。如果角度是 180,那么 B.y 应该不会影响 B 的哪一侧,对吧?
  • 当我使用标准数学系统绘制这些数据时 - CCW,OX 轴向右,然后,正如你所写,B.y = 5 指向 B 是左侧,B'.y = 15 是正确的,两者案例是正确的。 Picture
  • 哦,好吧,所以我认为角度约定有问题。我在 cmets 中提到约定是顺时针向北,所以如果角度是 180,箭头不应该在你的图片中指向下方吗?
  • 如果north clockwise我们必须交换cos和sin(规则cos(90-alpha)=sin(alpha),反之亦然),所以两个结果将具有相同的符号
  • 非常感谢!这对我有用。
【解决方案2】:

你有:

  • 一个点A(A.x, A.y);
  • A 的移动方向以角度A.angle 给出;
  • 一个点B(B.x, B.y)

你想比较A的运动方向和向量AB的方向。

向量 AB 的坐标可以通过简单的减法计算:

AB.x = B.x - A.x
AB.y = B.y - A.y

您可以使用atan2 计算与方向矢量 AB 对应的角度。方便的是,该函数是大多数编程语言标准数学库的一部分。

在使用 atan2 时,我们必须注意约定。在 cmets 中,您指定了您想要顺时针方向的约定。有关其他约定,请参阅Wikipedia: atan2 and conventions。 我们还必须将弧度转换为度数,这可以通过转换系数180 / pi 轻松完成。

AB.angle = atan2(AB.x, AB.y) * 180 / pi
if AB.angle < 0:
    AB.angle = AB.angle + 360

那么我们要做的就是检查 AB.angle 是在区间 [A.angle - 180°, A.angle](左),还是在区间 [A.angle, A.angle + 180°] (对),同时要小心,因为所有计算都是模 180°。

// assuming A.angle > 0 && A.angle < 360
if A.angle > 180:
    if AB.angle > A.angle - 180 && AB.angle < A.angle:
        return "Left"
    else:
        return "Right"
else: // A.angle < 180
    if AB.angle > A.angle && AB.angle < A.angle + 180:
        return "Right"
    else:
        return "Left"

【讨论】:

  • 我尝试了以下操作:A.x = 10,A.y = 10,A.angle = 270 和 B.x = 5,B.y = 5,但结果是“左”,但我认为应该是“对”?
  • @jimmone A.angle = 270 与北顺时针约定意味着 A 正在向西移动。 B(5,5) 和 A(10,10) 表示 B 位于 A 的西南方向。如果您面向西方,则西南方向的点在您的左侧,而不是您的右侧。
  • @jimmone 除非您对 x 和 y 使用不同的约定?我忘了问。除了 x->east 和 y->north 之外,我从不使用其他任何东西,并且没有意识到您可能正在使用其他约定。
  • 哦,对了,这很好。我在想y->南。这可能解释了为什么我所做的一切都给了我意想不到的结果。我正在处理地理坐标(纬度,经度),所以我认为约定应该是 y->north。
【解决方案3】:

让我们分手吧。

  • 我们有一条有向线 L,沿方向 a(表示角度)穿过点 A。
  • 我们得到了 B 点。
  • 问题是:B 在 L 的左边还是右边?

我们需要的是穿过 A 和 B 的线的角度(相对于“北”,也就是正 y 轴)。这使我们能够比较这些角度:

  • 如果差值为 -180°..0° 或 180°..360°(弧度为 -pi..0 或 pi..2pi),则 B 位于 L 的左侧,
  • 如果差异在 -360°..-180° 或 0°..180°(弧度为 -2pi..-pi 或 0..pi),则 B 在 L 的右侧。

如果您的 0° 角为“东,逆时针”(按照数学惯例),则更容易找到正确的数学运算,但我们只需交换 x 和 y 就可以了(他们'已经在以下几行中交换了!)。

我们仅从点获得那个角度(我们称之为 b),但起初,它会以弧度(而不是度数)为单位:

b_rad = Math.atan((A.x - B.x) / (A.y - B.y));

您没有指定角度是度还是弧度。假设度数,结果需要从弧度转换:

b_deg = b_rad * (180 / Math.PI);

现在你只需要拿差价:

delta = a_deg - b_deg;

并在我上面概述的比较中使用该增量。

(如果我想错了,这个数学得出的结果与所需要的结果相反——在这种情况下,您需要在 delta 计算中交换 a_deg 和 b_deg)

【讨论】:

  • 我尝试了以下操作:A.x = 10,A.y = 10,A.angle = 180 和 B.x = 5,B.y = 5 我得到 delta = -135,剩下的。如果我改变 B.y = 15 我得到 delta = -255,这是正确的,但我认为这是不正确的。如果角度是 180,那么 B.y 应该不会影响 B 的哪一侧,对吧?
  • @jimmone 如果 delta 角度正好是 0° 或 180°,“左”和“右”没有意义,你需要第三个状态“在线”——除非您将其定义为向左或向右解析。但这取决于应用程序。
【解决方案4】:

if pointB.x &lt; pointA.x 在左侧。

if pointB.x &gt; pointA.x 在右侧。

如果他们是平等的,你真的不能说谁在左边或右边。

(也就是说,当然假设您的坐标空间在 x 轴上从左到右)

【讨论】:

  • 感谢您的回答,但我也需要考虑角度,例如,如果角度为 270 度,我需要知道 B 点是否在 A 的“北”侧。
猜你喜欢
  • 2014-05-05
  • 1970-01-01
  • 2019-04-09
  • 1970-01-01
  • 2017-11-21
  • 1970-01-01
  • 2016-07-16
  • 1970-01-01
  • 2012-05-29
相关资源
最近更新 更多