简体   繁体   中英

One-dimensional elastic collision

I'm trying to make a program that solves elastic collision of 2 balls on x axis.

I implemented these one-dimensional Newtonian equasions https://en.wikipedia.org/wiki/Elastic_collision#One-dimensional_Newtonian , yet the program doesnt work as expected, can anyone giv me a clue what i am missing? thanks My code is as follows.

#include "ball.h"
#include <iostream>
#include <cmath>
Ball::Ball(float r, float pos_x, float pos_y, sf::Color color, sf::RenderWindow& window)
{
    m_mass =r;
    radius =r;
    c= color;
    x = pos_x;
    y = pos_y;
    vx=5;
    vy=5;
    m_window = &window;
    this->setFillColor(c);
    this->setRadius(radius);
    this->setPosition(x,y);
    this->setPointCount(20);
    this->setOrigin(radius, radius);
}

void Ball::moveBall()
{
    x+=vx;
    this->setPosition(x,300);

}

void Ball::bounce()
{
    if(x>= width - radius)
        vx = -vx;
    if(x<= 0 + radius)
        vx = -vx;
}

bool Ball::checkCollision(Ball &ball)
{
    distance_x = (x + radius) - (ball.x + ball.radius);
    distance_y = (y + radius) - (ball.y + ball.radius);
    distance = std::sqrt((distance_x*distance_x) + (distance_y*distance_y));


    if(distance <= radius + ball.radius)
    {
        std::cout << "collision detected" << "\n";
        return true;
    }
    else
        return false;
}

void Ball::resolveCollision(Ball &ball)
{
   vx  = (((m_mass- ball.m_mass) *vx) + (2*ball.m_mass*ball.vx)) /(m_mass+ball.m_mass);
   ball.vx  =  (((ball.m_mass-m_mass)*ball.vx) +(2* m_mass*vx))/(m_mass+ball.m_mass);


    std::cout << "vx " << vx << "\n";
    std::cout << "ball vx " << ball.vx << "\n";
    std::cout << "========================" << "\n";
}



void Ball::display()
{
    m_window->draw(*this);
}

You modify vx , but then accidentally used the modified value of vx in the calculation of ball.vx , whereas you actually intended to use the unmodified (initial) value of vx in the calculation of ball.vx before it was modified by the collision adjustment.

vx  = (((m_mass- ball.m_mass) *vx) + (2*ball.m_mass*ball.vx)) /(m_mass+ball.m_mass);
ball.vx  =  (((ball.m_mass-m_mass)*ball.vx) +(2* m_mass*vx))/(m_mass+ball.m_mass);
                                                        ^^

Just preserve the value of vx in a temporary variable so that its original value can be used in the computation of ball.vx .

float vx0 = vx; // save initial value of vx
vx  = (((m_mass- ball.m_mass) *vx) + (2*ball.m_mass*ball.vx)) /(m_mass+ball.m_mass);
ball.vx  =  (((ball.m_mass-m_mass)*ball.vx) +(2* m_mass*vx0))/(m_mass+ball.m_mass);
                                                        ^^^

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM