javascript - 两条线的交点,一种情况有效,另一种情况无效
问题描述
我有这个代码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 }
];
有什么帮助吗?
解决方案
我一直在寻找完全相同的问题,直到我最终为这些问题编写了自己的一套解决方案:
首先,您需要知道两个线段是否相交,此函数返回 true 或 false: https ://github.com/NetworkGraphs/graphysics/blob/79f9fe40ed5851867bf49a2eb2c96dcd61ef9dc5/libs/geometry.js#L206
一旦你确定他们这样做,你就不会被零除,你可以将它们视为相对简单的两条线相交问题: https ://github.com/NetworkGraphs/graphysics/blob/79f9fe40ed5851867bf49a2eb2c96dcd61ef9dc5/libs/geometry.js #L165
现在总结一下,如果你有一个多边形和一条线,你可以从这个函数中得到启发,我有一个盒子和一条线的交集。我使用角度来检查我必须在哪一侧执行相交测试,但是您可以使用第一个 profided 函数来了解您必须使用哪个 plygon 边缘来执行相交测试。 https://github.com/NetworkGraphs/graphysics/blob/79f9fe40ed5851867bf49a2eb2c96dcd61ef9dc5/libs/geometry.js#L122
请注意,您可能需要调整 epsilon 值,因为我已将其设置为 1,因为一个像素已经太小了。
我不能保证这是计算效率方面的最佳方式,但可以肯定的是,对于所有情况,它们对于每个零的任何除法都是安全且稳健的,因为我在任何导致除法的操作之前执行 epsilon 检查.
你可以在这个演示中看到整个东西在现场运行,我用它来绘制一个图形,我需要找到边缘的箭头会接触到顶点标签框的位置。 https://networkgraphs.github.io/graphysics/
推荐阅读
- python - 如何单击 selenium python 中的保存按钮?不断收到 StaleElementReferenceException
- php - Nested function inside While loop - PHP
- beautifulsoup - Python bs4 提取正确的表格内容
- javascript - 如何获取具有两个动态变量的 JSON 数据?
- android - RSA 没有正常工作
- html - 单击时如何仅更改离子列表中的一种离子项颜色?
- python-3.x - 导入 CSV 作为数据库 Django
- c# - 需要对我的代码进行哪些更改才能在 Revit 中创建新的 3D 透视图?
- python - Python:使用 BeautifulSoup 获取 href 的 URL 时遇到问题
- sql - 复制同一表的多行但具有不同的 id 并将复制行的旧 id 存储在列名 old ids 中