Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm trying to fake angular velocity on my vehicle when it hits a wall by getting the dot product of the normal of the edge the car is hitting and the vehicle's velocity:

            Vector2D normVel = new Vector2D();
            normVel.equals(vehicle.getVelocity());
            normVel.normalize();
            float dot = normVel.dot(outNorm);
            dot = -dot;
            vehicle.setAngularVelocity(vehicle.getAngularVelocity() +
                    (dot * vehicle.getVelocity().length() * 0.01f));

outNorm is the normal of the wall.

The problem is it only works half the time. It seems no matter what, the car always goes clockwise.

If the car should head clockwise:

--------------------------------------
       /
      /

I want the angular velocity to be positive, otherwise if it needs to go CCW:

--------------------------------------
       \
        \

Then the angular velocity should be negative...

What should I change to achieve this?

Thanks

Hmmm...

Im not sure why this is not working...

        for(int i = 0; i < buildings.size(); ++i)
        {
            e = buildings.get(i);
            ArrayList<Vector2D> colPts = vehicle.getRect().getCollsionPoints(e.getRect());

            float dist = OBB2D.collisionResponse(vehicle.getRect(), e.getRect(), outNorm);
            for(int u = 0; u < colPts.size(); ++u)
            {
                Vector2D p = colPts.get(u).subtract(vehicle.getRect().getCenter());
                vehicle.setTorque(vehicle.getTorque() + p.cross(outNorm));
            }
share|improve this question

2 Answers 2

up vote 3 down vote accepted

enter image description here

The main problem is that the dot product of the velocity and wall normal is only based on the 'smallest' angle between these two vectors, so doesn't take into account if the vector is coming from the right or left.

You will need a vector along the wall and get the dot product of that and the vehicle velocity. The sign of the result will tell you whether to go cw or ccw.

Of course you can use the wall's normal to get the vector along the wall

Vector2D alongWall=new Vector2D(outNorm.y,-outNorm.x); //get perpendicular vector 

So your code should look something like this;

       Vector2D normVel = new Vector2D();
        normVel.equals(vehicle.getVelocity());
        normVel.normalize();
        float dot = normVel.dot(outNorm);
        dot = -dot;
        Vector2D alongWall=new Vector2D(outNorm.y,-outNorm.x); //get perpendicular vector 
        float cw=alongWall.dot(normVel);
        if(cw<0)//check which direction we are coming from
            dot=-dot; //coming from the right, so reverse direction of rotation

        vehicle.setAngularVelocity(vehicle.getAngularVelocity() +
                (dot * vehicle.getVelocity().length() * 0.01f));
share|improve this answer
    
Could you give me an example in code please? –  Milo Nov 20 '12 at 20:33
    
How do I get the vector along the wall? –  Milo Nov 20 '12 at 20:33

Just a moment. (Ha ha, you'll get this at the end of this post).

The dot product between acute vectors (angle less than 90 degrees) is always positive. For obtuse angles the dot product is always negative. The force vector impacting the car points opposite the normal of the car usually, so the dot product of the force vector and the car surface normal is always obtuse (negative).

I don't think you should hack like this, doing the basic physics calculations is easier and will look a lot better.

A basic moment is computed as

moment = cross( r, F )
  • r Is the vector from the centroid to the point of impact
  • F is the force vector

If r x F is +, you have CCW rotation. If rxF is -, you have CW rotation. Note that you only need to do this in 2D, because the car is grounded.

Some examples of finding moments with basic vectors below. You should see that it checks out with your intuition based on the red dot car centroid.

enter image description here

share|improve this answer
    
+1; physically based solutions give better results and in this case it's no any harder to use physics than to do a hack. BTW the moment here is a torque, so you can divide it by the moment of inertia scalar for the car and then use it directly as an angular acceleration (not angular velocity). –  Nathan Reed Nov 20 '12 at 21:26
    
One thing, how do I calculate the Force vector? –  Milo Nov 20 '12 at 21:37
    
It would be perpendicular to the wall you're hitting (use the wall normal). The magnitude of the force is actually F=ma, so it depends on the mass of the car (m) (which you'll have to tune), and the acceleration the wall exerts on the car body (which depends on car velocity.. car coming to a crushing stop in 5cm is going to be a large acceleration in the direction of the wall normal) –  bobobobo Nov 20 '12 at 21:56

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.