【问题标题】:line segment intersection algorithm线段相交算法
【发布时间】:2016-08-08 03:01:38
【问题描述】:

我正在按照“算法简介”一书来实现线段相交,但我对算法得到的结果感到困惑。我一定在算法中遗漏了一些东西,我需要一些帮助才能找到它。检查以下sn-p代码:

glm::i16vec2 contourLineStart(1057,1762);
glm::i16vec2 contourLineEnd(1057,0);

glm::i16vec2 hilbertLineStart(-1762,-2466);
glm::i16vec2 hilbertLineEnd(-1734,-2466);

正如你所看到的,两条线是用上面定义的坐标形成的,你也可以想象 contourLine 是由 contourLineStart 和 contourLineEnd 制定的,而 hilbertLine 可以由 hilbertLineStart 和 hilbertLineEnd 制定。而且这两条线不可能相交。不幸的是,算法告诉我有一个交叉点,让我很困惑。剩下的代码如下:

glm::i32 direction(const glm::i16vec2& pi,
                   const glm::i16vec2& pj,
                   const glm::i16vec2& pk)
{
    return ((pk.x - pi.x)*(pj.y - pi.y)) - ((pj.x - pi.x)*(pk.y - pi.y));
}

int main()
{
   glm::i16vec2 contourLineStart(1057,1762);
   glm::i16vec2 contourLineEnd(1057,0);

   glm::i16vec2 hilbertLineStart(-1762,-2466);
   glm::i16vec2 hilbertLineEnd(-1734,-2466);

   glm::i16 d1 = direction(contourLineStart,contourLineEnd,hilbertLineStart);
   glm::i16 d2 = direction(contourLineStart,contourLineEnd,hilbertLineEnd);
   glm::i16 d3 = direction(hilbertLineStart,hilbertLineEnd,contourLineStart);
   glm::i16 d4 = direction(hilbertLineStart,hilbertLineEnd,contourLineEnd);


   if((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0) &&
      (d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0))
   {
    std::cout << "There is a intersection" << std::endl;
   }
   else
   {
    std::cout << "There is no intersection" << std::endl;
   }

return 0;
}

在这个过程中我有什么遗漏吗?

谢谢

【问题讨论】:

  • 编码问题在这里是题外话,所以我将其移至 Stack Overflow。您应该从尝试调试代码开始:手动执行代码,查看每一行发生的情况,并检查它是否有意义。我很怀疑在这里使用 16 位整数;似乎它只是要求整数溢出。
  • 我不是 C++ 专家,但预计因为您似乎在对 16 位整数类型进行算术运算(猜测这就是 i16 的意思),所以中间结果会溢出。尝试将每个乘法的操作数转换为 32 位 int。
  • 感谢您的提示,简单的 int 工作正常。我相信您对 16 位整数的看法是正确的。我将它们重新声明为简单的 int,现在交集测试似乎工作正常。

标签: c++ algorithm geometry glm-math


【解决方案1】:

这里:

if((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0) &&
  (d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0))

添加一些括号以避免(a || b &amp;&amp; c || d)的歧义:

if(((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) &&
  ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0)))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-21
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-26
    • 1970-01-01
    • 2014-10-13
    相关资源
    最近更新 更多