Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


gracicot

Member Since 16 Feb 2013
Offline Last Active Mar 05 2013 02:01 PM

Topics I've Started

Trouble implementing SAT collision

16 February 2013 - 03:20 PM

Hi there,

 

I am currently writing a little engine from scratch but I have currently trouble implementing the SAT collision algorithm. I'm able to detect collision with stunning precision but unfortunately, I can't get the right collision response. Sometimes the object bounce, but sometime the object is shallowed inside the other one and moving inside very quickly. It's been around a week I try to figuring out what's the problem and it's get worse over time. Here's a sample of my code:

 

The collision detection:

Vector2 Polygon::projection(double angle) const
{
    Vector2 axis = {cos(angle), sin(angle)};
    Vector2 result_projection;
    Vector2 current;


    std::list<Vector2>::const_iterator verticle = _vertex.begin();

    current = *verticle;
    current.setAngle(_angle + current.getAngle());

    result_projection.x = axis.dot(current + _position);
    result_projection.y = result_projection.x;

    for(verticle++ ; verticle != _vertex.end() ; verticle++)
    {
        current = *verticle;
        current.setAngle(_angle + current.getAngle());
        double p = axis.dot(current + _position);
        if(p < result_projection.x)
        {
            result_projection.x = p;
        }
        else if(p > result_projection.y)
        {
            result_projection.y = p;
        }
    }

    return result_projection;
}

Vector2 Polygon::overlap(const SAT_able& other) const
{
    Vector2 overlap;
    overlap.setLenght(std::numeric_limits< double >().max());
for(double angle : getAngles())
    {
        Vector2 projectionThis = this->projection(angle);
        Vector2 projectionOther = other.projection(angle);

        if(projectionThis.x < projectionOther.x && projectionThis.y > projectionOther.x && projectionThis.y < projectionOther.y)
        {
            if(overlap.getLenght() > projectionThis.y - projectionOther.x)
            {
                overlap = {projectionThis.y - projectionOther.x, 0};
                overlap.setAngle(angle);
            }
        }
        else if(projectionThis.x > projectionOther.x && projectionThis.y < projectionOther.y)
        {
            if(overlap.getLenght() > projectionThis.y - projectionThis.x)
            {
                overlap = {projectionThis.y - projectionThis.x, 0};
                overlap.setAngle(angle);
            }
        }
        else if(projectionThis.x > projectionOther.x && projectionThis.x < projectionOther.y && projectionThis.y > projectionOther.y)
        {
            if(overlap.getLenght() > projectionOther.y - projectionThis.x)
            {
                overlap = {projectionOther.y - projectionThis.x, 0};
                overlap.setAngle(angle);
            }
        }
        else if(projectionThis.x < projectionOther.x && projectionThis.y > projectionOther.y)
        {
            if(overlap.getLenght() > projectionOther.y - projectionOther.x)
            {
                overlap = {projectionOther.y - projectionOther.x};
                overlap.setAngle(angle);
            }
        }
        else
        {
            return Vector2(0,0);
        }
    }
    return overlap;
}

std::vector< double > Polygon::getAngles() const
{
    std::vector<double> angles;
    Vector2 previous = *_vertex.rbegin();
    previous.setAngle(_angle + previous.getAngle());
for(Vector2 current : _vertex)
    {
        current.setAngle(_angle + current.getAngle());
        angles.push_back((previous - current).getAngle() - (pi / 2));
        previous = current;
    }
    return angles;
}

 

 

 
 

The reponse code:

		Vector2 nearest = sat->distance;

		point->setPulse("collision", nearest * point->getMass());

		EventManager::triggerEvent("collision", new CollisionEventArgs(*sat, *point))

If you want to see more of my code check the projection on github: https://github.com/gracicot/subgine

 

EDIT: added more code


PARTNERS