You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++性能关键场景下,检查线段包含点的最快方法是什么?

性能关键场景下,线段包含点的高效检测方法

我知道网上有很多关于如何检查线段是否包含点的讨论,但我的核心问题是:在性能敏感的应用中,哪种方法效率最高?

查阅各类技术资料后,我总结出三种通用方法:

基于距离计算的方法

float distance(Vector2 a, Vector2 b)
{
    return std::sqrtf(std::powf((a.x - b.x), 2.f) + std::powf((a.y - b.y), 2.f));
}

bool containsPoint(Vector2 lineP, Vector2 lineQ, Vector2 point)
{
    return distance(lineP, point) + distance(point,lineQ) == distance(lineP, lineQ);
}

我直接排除了这种方法,三次平方根运算的开销太大,完全不符合性能要求。

基于斜率计算的方法

bool containsPoint(Vector2 lineP, Vector2 lineQ, Vector2 point)
{
    float slope = (lineP.y - lineQ.y) / (lineP.x - lineQ.x);
    float c = lineP.y - lineP.x * slope;
    
    float minX = std::min(lineP.x, lineQ.x);
    float maxX = (minX == lineP.x) ? lineQ.x : lineP.x;
    
    return point.x * slope + c == point.y && point.x >= minX && point.x <= maxX;  
}

这是我最初想到的实现,但不确定它的性能是不是最优的。而且这个方法存在明显缺陷:当线段垂直于X轴时,lineP.x - lineQ.x为0,会触发除以0的错误,实际使用时必须添加额外的分支判断,这会进一步降低性能。

基于叉乘与点乘的方法

bool containsPoint(Vector2 lineP, Vector2 lineQ, Vector2 point)
{
    float crossproduct = (point.y - lineP.y) * (lineQ.x - lineP.x) - (point.x - lineP.x) * (lineQ.y - lineP.y);

    if (fabs(crossproduct) > std::numeric_limits<float>::epsilon())
    {
        return false;
    }
    float dotproduct = (point.x - lineP.x) * (lineQ.x - lineP.x) + (point.y - lineP.y)*(lineQ.y - lineP.y);
    if (dotproduct < 0.f)
    {
        return false;
    }

    float squaredlengthba = (lineQ.x - lineP.x)*(lineQ.x - lineP.x) + (lineQ.y - lineP.y)*(lineQ.y - lineP.y);
    if (dotproduct > squaredlengthba)
    {
        return false;
    }

    return true;
}

这个方法代码量比斜率法多,但完全不需要除法操作——众所周知除法的运算速度大概只有乘法的1/10,所以理论上这是更高效的方案。它通过叉乘判断点是否落在直线上,再通过点乘判断点是否处于线段的范围内,既没有浮点运算的隐患,逻辑也更严谨。

除此之外,有没有比这种方法更快的实现?

内容的提问来源于stack exchange,提问作者JensB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 17:27:35