【问题标题】:How to Handle Corners in Segment Intersection Checks如何处理线段相交检查中的拐角
【发布时间】:2020-07-24 20:15:38
【问题描述】:

我正在创建一个使用光线段相交检查的光线投射模拟。在两条线段相交的拐角处,代码确定没有交叉点。

我已尝试将段延长一小段距离,但这会导致模拟出现其他问题。在这种情况下我该怎么办?

交叉口检查代码:

struct Point {
    double x, y;
}

std::unique_ptr<Point> Ray::cast(const Boundary& wall) const {
    const double x1 = wall.a.x;
    const double y1 = wall.a.y;
    const double x2 = wall.b.x;
    const double y2 = wall.b.y;

    const double x3 = pos.x;
    const double y3 = pos.y;
    const double x4 = pos.x + dir.x;
    const double y4 = pos.y + dir.y;

    const double den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
    if (den == 0) {
        return nullptr;
    }

    const double t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / den;
    const double u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / den;

    if ((t > 0.0f && t < 1.0f) && u > 0.0f) {
        return std::make_unique<Point>(x1 + t * (x2 - x1), y1 + t * (y2 - y1));
    }
    else {
        return nullptr;
    }
}

交叉路口故障:

【问题讨论】:

  • 您需要覆盖浮点错误。 t 是射线上截距的单位位置。 u 是这个单元在墙上截取的位置。要获得墙的端点,请在最后的语句u &gt;= 0.0f &amp;&amp; u &lt;= 1.0f 中包含墙端点u == 0.0fu == 1.0f,但错误可能偶尔会失败,因此请稍微扩展墙u &gt;= -EPSILON &amp;&amp; u &lt;= 1.0f + EPSILONEPSILON 是一个非常小的值,例如 EPSILON = 0.000001f
  • @Blindman67 据我所知,在这种情况下不需要 u 到 >= 的变化消除了所有的交叉口故障。如果您想重新提交作为答案,我会将其标记为解决方案。

标签: c++ math game-physics


【解决方案1】:

一个标准答案是根据与投射光线的关系来定义问题。这是known 如何将平面划分为“左侧”、“右侧”和可选“在线”上的非重叠区域。 (最后一个是可选的,因为您可以任意将其包含在其他两个中的一个中。)如果两个端点位于不同的区域,则一条射线会撞击一条线段。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多