0

我想擦除半径 < 20,但收到矢量下标超出范围错误。

for (int i = 0; i < ball.size() ; i++)
    for (int j = i + 1; j < ball.size(); j++)
    {
        
        int a = ball[i].x - ball[j].x;
        int b = ball[i].y - ball[j].y;
        if (sqrt(a * a + b * b) <= ballr[i]+ballr[j])
        {
            wx[i] = -wx[i];
            wx[j] = -wx[j];
            wy[i] = -wy[i];
            wy[j] = -wy[j];
            ballr[i] =ballr[i]- ballr[i] * 0.1;
            ballr[j] =ballr[j]- ballr[j] * 0.1;
        }
    }
for (int i = ball.size() - 1; i >= 0; i--)
{
    if (ballr[i] < 20)
    {
        ball.erase(ball.begin() + i);
    }
    else
    {
        i--;
    }
}
4

2 回答 2

0
for (int i = ball.size() - 1; i >= 0; i--)
{
    if (ballr[i] < 20)
    {
        ball.erase(ball.begin() + i);
    }
    else
    {
        i--;
    }
}

如果,在某些情况下,ballr[i] >= 20,则该else部分被执行,并且您递减i. 并且,在循环结束时,您再次for递减。i

相反,您希望在听到值时增加。 i

for (int i = ball.size() - 1; i >= 0; i--)
{
    if (ballr[i] < 20)
    {
        ball.erase(ball.begin() + i);
        ++i;
    }
}
于 2021-11-04T14:00:05.343 回答
0

超出范围的错误很可能与ballrwxwy向量之一有关。不幸的是,您没有提供分配它们的代码。

在任何情况下,您的代码都充满了错误。我假设您想检测各种大小的移动气泡之间的碰撞。

您将每个气泡的信息保存在几个数组中,我看到 ball[]、wx[]、wy[]、ballr[]... 这些数组必须始终保持同步,尤其是在添加或擦除 balls 时。换句话说,这种安排就像是在呼吁将错误集中在您的代码上:),就像这里的情况一样。

您是否考虑过将与球相关的所有信息整合到一个地方?这是 OOP 的基础,它将使管理所有这些信息变得更加容易。

例子:

struct ball
{
    double x;
    double y;
    double radius;
    double wx;
    double wy;  

    void reverseCourse()
    {
        wx = -wx;
        wy = -wy;
    }

    // a function to compute distance:
    friend double getDistance(const ball& a, const ball& b)
    {
        double dx = b.x - a.x;
        double dy = b/y - a.y;
        return sqrt((dx * dx) + (dy * dy)); 
    }

    friend bool collide(const ball& a, const ball& b)
    {
        return getDistance(a, b) <= (a.radius + b.radius);
    }

};

//...

std::vector<ball> balls;
//...


for (size_t i = 0; i < balls.size(); ++i)
{
    for (size_t j = i + 1; j < balls.size(); ++j)
    {
        if (collide(balls[i], balls[j]))
        {
            balls[i].reverseCourse();  // this will probably not work as 
            balls[j].reverseCourse();  // you'd like, a bit of maths 
                                       // will be needed for a more 
                                       // realistic visual effect
            balls[i].radius *= .9;
            balls[j].radius *= .9;
        }
    }
}

// Since all information is kept in one single location, removing balls is a simple operation
// you could do it as you were attempting to do it before (minus the double decrement bug), 
// or using the std library.

// for c++11 and later:
balls.erase(std::remove_if(balls.begin(), balls.end(), 
                          [](const ball& b) { return (b.radius < 20); }),
            bakls.end());

// for c++98
struct local  // any dumb name will do
{
    static bool smallRadius(const ball& b) { return (b.radius < 20); };
};

balls.erase(std::remove_if(balls.begin(), balls.end(), local::smallRadius),
            balls.end());
于 2021-11-04T14:24:13.783 回答