【问题标题】:point of intersection of two lines, one case works another it doesnt两条线的交点,一侧起作用,另一侧不起作用
【发布时间】:2020-07-13 05:47:37
【问题描述】:

我有这个代码https://codepen.io/octaviandd/pen/dyoaJVZ?editors=0010

基本上是一个多边形和一条线,当我移动鼠标并穿过整个多边形时,我需要找到线和多边形线之间的交点(只是多边形的左侧和右侧)。我对左侧和右侧使用相同的算法,左侧有效,右侧无效。

左侧:

if (
    (positions.a1x === positions.a2x && positions.a1y === positions.a2y) ||
    (points[0].x === points[6].x && points[0].y === points[6].y)
  ) {
    return false;
  }

  let denominator =
    (points[6].y - points[0].y) * (positions.a2x - positions.a1x) -
    (points[6].x - points[0].x) * (positions.a2y - positions.a1y);

  if (denominator === 0) {
    return false;
  }

  let ua =
    ((points[6].x - points[0].x) * (positions.a1y - points[0].y) -
      (points[6].y - points[0].y) * (positions.a1x - points[0].x)) /
    denominator;
  let ub =
    ((positions.a2x - positions.a1x) * (positions.a1y - points[0].y) -
      (positions.a2y - positions.a1y) * (positions.a1x - points[0].x)) /
    denominator;

  if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {
    return false;
  }

  let x = positions.a1x + ua * (positions.a2x - positions.a1x);
  let y = positions.a1y + ua * (positions.a2y - positions.a1y);

右侧:

if (
    (positions.a1x === positions.a2x && positions.a1y === positions.a2y) ||
    (points[2].x === points[3].x && points[2].y === points[3].y)
  ) {
    return false;
  }

  let denominator2 =
    (points[3].y - points[2].y) * (positions.a2x - positions.a1x) -
    (points[3].x - points[2].x) * (positions.a2y - positions.a1y);

  if (denominator2 === 0) {
    return false;
  }

  let ua2 =
    ((points[3].x - points[2].x) * (positions.a1y - points[2].y) -
      (points[3].y - points[2].y) * (positions.a1x - points[2].x)) /
    denominator;
  let ub2 =
    ((positions.a2x - positions.a1x) * (positions.a1y - points[2].y) -
      (positions.a2y - positions.a1y) * (positions.a1x - points[2].x)) /
    denominator;

  if (ua2 < 0 || ua2 > 1 || ub2 < 0 || ub2 > 1) {
    return false;
  }

  let x2 = positions.a1x + ua2 * (positions.a2x - positions.a1x);
  let y2 = positions.a1y + ua2 * (positions.a2y - positions.a1y);

如果我从左到右穿过多边形,碰撞点似乎向内,如果我从右到左,碰撞点似乎向外;如果我的线来自左侧并靠近右侧但没有碰到它,算法仍然会以某种方式找到假碰撞。

多边形的初始坐标:

    const points = [
      { x: 100, y: 100 },
      { x: 200, y: 50 },
      { x: 300, y: 50 },
      { x: 400, y: 200 },
      { x: 350, y: 250 },
      { x: 200, y: 300 },
      { x: 150, y: 300 }
    ];

有什么帮助吗?

【问题讨论】:

  • 计算ua2ub2时,必须除以denominator2,而不是denominator。为了避免此类错误,我建议您编写一个单独的函数来计算交集,而不是在同一范围内复制具有相似参数的代码。

标签: javascript algorithm svg graph polygon


【解决方案1】:

我一直在寻找完全相同的问题,直到我最终为这些问题编写了自己的一套解决方案:

请注意,您可能需要调整 epsilon 值,因为我已将其设置为 1,因为一个像素已经太小了。

我不能保证这是计算效率方面的最佳方式,但可以肯定的是,对于所有情况,它们对于任何零除法都是安全且稳健的,因为我在任何操作前执行 epsilon 检查到一个部门。

你可以在这个演示中看到整个东西正在运行,我用它来绘制一个图形,我需要找到边缘的箭头会接触到顶点标签框的位置。 https://networkgraphs.github.io/graphysics/

【讨论】:

    猜你喜欢
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多