【问题标题】:my object::collides(object * o) function always returns true, but doesn't do anything我的 object::collides(object * o) 函数总是返回 true,但什么也不做
【发布时间】:2019-01-07 18:21:58
【问题描述】:

我有一个返回布尔值的函数。这个函数在编译时似乎什么都不包含,并且总是会返回 true,同时也会跳过我放入其中的所有对 cout 或 cin 的调用。看看它实际上在做什么。发生了什么事,我该如何解决这个问题。

在我的故障排除过程中,我有,

  • 在 object::collides 处使用带有断点的 GDB,这导致函数被调用但没有向控制台输出任何内容
  • 将我的对象编号并比较程序认为正在发生碰撞的对象与正在发生碰撞的对象。如果它通过了接近测试,则程序认为对象正在碰撞,证明它总是返回 true。
  • 尝试了各种其他方法试图弄清楚发生了什么,但都没有答案

在 object.cpp 中:

bool object::collides(object * other)
{
   std::vector<point> a_pnt = getBounds();
   std::vector<point> b_pnt = other->getBounds();
   for (int i = 0; i < a_pnt.size(); i++)
   {
       for (int j = 0; j < b_pnt.size(); j++)
       {
          point v1 = a_pnt[i];
          point v2 = a_pnt[(i+1)%a_pnt.size()];
          point v3 = b_pnt[j];
          //edit: fixed typo
          point v4 = b_pnt[(j+1)%b_pnt.size()];

          double num_1 = ((v3.x - v1.x) * -(v4.y - v3.y)) - (-(v4.x - v3.x) * (v3.y - v1.y));
          double num_2 = ((v2.x - v1.x) * (v3.y - v1.y)) - ((v3.x - v1.x) * (v2.y - v1.y));
          double den =((v2.x - v1.x) * -(v4.y - v3.y)) - (-(v4.x - v3.x) * (v2.y - v1.y));
          double frac_1 = num_1 / den;
          double frac_2 = num_2 / den;

          //debug code start
          std::cout << num_1 << "/" << den << "=" << frac_1 << std::endl;
          std::cout << num_2 << "/" << den << "=" << frac_2 << std::endl;
          std::cout << (frac_1 > 0.0) << " " << (frac_1 < 1.0) << " " << (frac_2 > 0.0) << " " << (frac_2 < 1.0) << std::endl;
          std::cout << std::endl;

          std::string hahah;
          std::cin >> hahah;
          //end debug code

          //edit: fixed conditional
          if((frac_1>0.0)&&(frac_1<1.0)&&(frac_2>0.0)&&(frac_2<1.0));
             return true;
       }
   }
   //edit: fixed conditional
   return false;
}

在函数mode::step()中的mode.cpp中:

for (int i = 0; i<onScreen.size(); i++)
{

    object * o1 = onScreen[i];
    for(int j = i+1; j<onScreen.size(); j++)
    {
        object * o2 = onScreen[j];
        if(o1->getVectorLength(o2)<50){

            std::cout << "Checking collisions for objects " << i << " and " << j << std::endl;

            if(o1->collides(o2))
            {
                 std::cout << "somthing collided\n";

            }
        }
    }
}

输出:

Checking for Collisions

Checking collisions for objects 0 and 11
somthing collided
Checking collisions for objects 1 and 8
somthing collided
Checking collisions for objects 1 and 18
somthing collided
Checking collisions for objects 1 and 26
somthing collided

预期结果是“碰撞”函数输出到屏幕或请求输入该字符串,这将表明它实际上正在正确地通过该部分代码。但是它不这样做。无论实际相交部分是真还是假,“碰撞”函数都会返回真,同时跳过我的所有调试代码,如输出所示。

编辑:

  • 修复了碰撞中的返回
  • 修正了一个错字
  • 还是不行。
  • 确实会考虑子弹/子弹组合而不是子弹/小行星或小行星/小行星的循环

  • 检查 getBounds 让我摸不着头脑......

    std::vector asteroid::getBounds() { //我的问题在这里,更仔细地检查你的函数:P //没有返回包含任何内容的向量。 标准::向量 t; //现在是 std::vector t = lyrs[0].pnts;

    for (int i = 0; i < t.size(); i++)
    {
        double x = t[i].x+location.x;
        double y = t[i].y+location.y;
        t[i] = point{x, y, t[i].z};
    }
    return t;
    

    }

  • 我认为实施得当

【问题讨论】:

  • 您无条件地返回您的内部for 循环。这意味着您可能根本没有循环,您只检查第一对值。您可能打算有条件地返回。
  • 你的代码有未定义的行为,编译器应该警告你不是object::collides()的所有路径都返回一个值。
  • @πάνταῥεῖ 它总是返回,前提是每个边界框至少有一个点,这可以保证。
  • 在不尝试通读数学的情况下询问:您的算法是否关心边界框点的顺序(顺时针/逆时针)?如果是,是否遵守该要求?
  • @FrançoisAndrieux 是的,我做到了,解决了这个问题,但仍然根本没有进入 for 循环。这是主要问题。

标签: c++ oop pointers boolean dynamic-cast


【解决方案1】:

问题出现在这一行:

if((frac_1>0.0)&&(frac_1<1.0)&&(frac_2>0.0)&&(frac_2<1.0)); //This semicolon here
    return true;

在 if 语句的末尾加上一个分号基本上结束了 if 语句。你写的相当于

if((frac_1>0.0)&&(frac_1<1.0)&&(frac_2>0.0)&&(frac_2<1.0))
{
}
return true;

修复它非常简单。只需删除分号:

if((frac_1>0.0)&&(frac_1<1.0)&&(frac_2>0.0)&&(frac_2<1.0))
    return true;

【讨论】:

  • 这是在我弄清楚我真正问题的一部分后进行的编辑,这是一个错字,不过,谢谢,如果它是实际代码,那将是一个问题(而且与我最初的代码相差不远确实),可悲的是,正如我在问题末尾所描述的那样,我真正的问题是(我真的应该发布一个答案)是我实际上并没有为我的一个对象返回一个包含任何内容的向量。跨度>
【解决方案2】:

所以我的问题很简单,而且有点“doh”。首先,我必须解决的未实现的问题是返回 true,无论我的数学是否真的正确完成,但由于这部分没有被击中,这不是真正的问题。感谢那些无论如何都注意到它的人。

问题一(如果返回 true,则否):

在collides.cpp中

for (int i = 0; i < a_pnt.size(); i++)
{
   for (int j = 0; j < b_pnt.size(); j++)
   {
       ...
       return true;
    }
 }

固定于:

for (int i = 0; i < a_pnt.size(); i++)
{
   for (int j = 0; j < b_pnt.size(); j++)
   {
       ...
      if((frac_1>0.0)&&(frac_1<1.0)&&(frac_2>0.0)&&(frac_2<1.0))
         return true;
    }
 }

第二个问题,也是主要的一个问题,根据评论者的建议,他的名字出现在上面的问题中,我仔细检查了我的 getter 的边界框。低,看哪,那是我的问题。虽然一开始我对他的建议不以为然,因为我认为我已经完全实现了那个 getter,但这是我的问题,学习宝贵的经验总是一件好事。

问题二(GetBounds实现不完整,导致返回空向量。):

在 asteroids.cpp 中:

std::vector asteroid::getBounds() 
{ 
    //my issue was here, check your functions a bit more closely :P 
    //wasn't returning a vector with anything in it. 
    std::vector<point> t; 
    //now it's 
    std::vector<point> t = lyrs[0].pnts;

    for (int i = 0; i < t.size(); i++)
    {
       double x = t[i].x+location.x;
       double y = t[i].y+location.y;
       t[i] = point{x, y, t[i].z};
    }
return t;
}

经验教训:即使您认为一切正常,但有时您却没有,您应该检查并仔细检查您正在调用的每个函数,以防您认为其中一个函数实际上没有工作正常工作。

【讨论】:

    猜你喜欢
    • 2011-02-14
    • 2014-05-04
    • 1970-01-01
    • 2021-01-29
    • 2014-07-22
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 2019-10-18
    相关资源
    最近更新 更多