js 怎么判断当前坐标离垂直坐标(90度)还是45度坐标,哪个更近?

js 怎么判断当前坐标离垂直坐标(90度)还是45度坐标,哪个更近?
如图:

最终需要的效果是这样的:
image.png

最终解决方案,使用了,javascript 2D向量库,http://victorjs.org

阅读 6.5k
7 个回答

如楼上所述
假设坐标是(x,y),则角度值为 const deg = Math.atan(y/x)*180/Math.PI
如果deg > 67.5则离90度角近,如果deg < 67.5则离45度角近,否则就是在中线上

补充: 如果是算4个象限8条线的话

// point0: 第一次坐标;point1: 第二次坐标
// 方法返回的是最近的那个线的角度值
function getDeg(point0, point1) {
  // 计算相对坐标(相当于让第一次坐标归零)
  const point = [point1[0] - point0[0], point1[1] - point0[1]];
  // 4个象限中8条线的角度
  const lineDegs = [0, 45, 90, 135, 180, 225, 270, 315];
  // 正负角度,这里的角度范围只有-90度到90度,所以还需要根据相对坐标校正角度
  let deg = Math.atan(point[1] / point[0]) * 180 / Math.PI;
  if (point[0] < 0) {
    deg += 180;
  }
  for (let i = 0; i < lineDegs.length; i++) {
    if (deg > lineDegs[i] && deg < lineDegs[i + 1]) {
      const middleDeg = (lineDegs[i] + lineDegs[i + 1]) / 2;
      return deg > middleDeg ? lineDegs[i + 1] : lineDegs[i]
    }
  }
}

getDeg([0,0], [1,2])

算角度就好了。45根90中线是67.5度

image.png
比较\( y^2 \) 与\( \frac{(x + y)^2}2 \) 的大小即可。
前者大则靠近y轴,后者大则靠近45°线。


解析:
高中数学向量点乘:

$$ a(x1, y1) \cdot b(x2, y2) = x1 \cdot x2 + y1 \cdot y2 = \lvert{a}\rvert \cdot \lvert{b}\rvert \cdot \cos\theta $$

可以得到两向量夹角的余弦:

$$ \cos\theta=\frac{x1 \cdot x2 + y1 \cdot y2}{\lvert{a}\rvert \cdot \lvert{b}\rvert} $$

比较距离大小就是比较夹角大小,夹角小则距离近;
而比较夹角可以转为比较余弦值。
cos函数在(0, π/2)内单调递减,因此余弦小,则夹角大。

上图中:

$$ \cos\angle{BOC} = \frac{0 \times x + 1 \times y}{1 \times \sqrt{x^2 + y^2}} \\ \cos\angle{AOC} = \frac{1 \times x + 1 \times y}{\sqrt2 \cdot \sqrt{x^2 + y^2}} $$

两个值都为正值,而我们只用比较大小,可以约去相同部分,并平方去根号后比较大小。
即比较 \( y^2 \) 与 \( \frac{(x + y)^2}{2} \) 的大小即可。

那么问题来了

image.png

你要的是 AB 和 AC 之间(到线的距离)比较,还是 AB 和 AD 之间进行比较(基于水平移动的接近点判断)

要算离 y 轴近还是离角平分线近,可以算角度。\( \angle{BOC} \) 的平分线到 x 正轴是 45 + 22.5 = 67.5 度角。所以只需要算 \( \arctan{\frac{y}{x}} \) 得到的角度是多大就能算出来了。不过 Math.atan() 的结果是弧度值,要 \( \cdot\frac{180}{\pi} \) 才是角度

const angle = Math.atan(y / x) * 180 / Math.PI

然后拿 angle67.5 比较,大于则是接近 y 轴,小于则是接近 45 度线。

虽然已有很多答案了,但感觉还是需要补充一个个人感觉更简单的方案:

直接比接x * 2y 的大小, x * 2 > y,则离45度线近; x * 2 < y ,则离90度近。

待验证。

其实题主还是需要回归到问题核心,要区别 1. 离正向竖直坐标轴近还是离45度射线近2. 离坐标轴近还是离坐标轴顺(逆)时针旋转45度后的轴近 这样两个不同的问题。

如果是1,则只能对1区间点进行比较,对于2是所有区间点的情况(这个在坐标锁定处理中可能会用到),这两种情况处理结果有时也不尽相同,这都需要根据原始要求来选择。

此外,还要给出两个距离值相等的情况(这个情况是必然存在的)时的处理策略。

以上都是实际工程应该要预先规范的部分。

其实我看了半天,没有找到题主到底需要什么,虽然其提供了一幅最终想要的效果的图,但上面又缺少了点与图的关系表达。

我根据题主最终选择向量图库来看,其实其需要是类似上面问题2 的。这样就可以直接根据向量角值判断点与8个轴靠近程度(直接就是与8个向量角差值绝对值的比较)

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题