what to do after collisions. making next move vector based on speed ,direction etc

Started by
3 comments, last by daktaris 19 years, 4 months ago
ok, im using avros algorithm to determine when my charachter colides with a wall. now i need to alter my application to be able to do something when a collision occours. i want my charachter to be able to slow down and turn , either left or right until he is no longer coliding with a wall. the problem is that i dont know how to create a vector based on the speed and direction of my charachter. at present, im moving him by simply incrementing the x value, or the z value, but im not using any functions to allow him to speed up or slow down or change direction and im wondering if someone could show me how. thanks all
I currently only use c# and directX9, in case its relivant and i didnt mention it in the post
Advertisement
I'm not sure if you mean that you want the character to actually bounce off of the wall or not, but all a vector really is is the three values representing the change in x, y, and z (or simply x and y for a 2d surface). So when the character turns, just use sine and cosine to determine the new values for the vector. Depending on how you want to deal with speeding up, you can either add to the vector every "frame" and factor in a bit of energy loss by lowering the magnitude ("length") of the vector (multiplying it by a scalar < 1), which will give you a nice slippery kind of effect (sort of like walking on ice), or you can throw out all of the directional information of the vector and simply deal with the magnitude to stop the character from sliding when they try to turn. For collisions, if you want the character to bounce off of the wall, simply take the angle of your character relative to the wall and then use the mirror image of it, and calculate the new vector based on that.
-~-The Cow of Darkness-~-
since my wall is an axis alligned bounding box, it has two vectors, max and min. from my understanding, i normalise theese, get the dot product of them and the resulting vector will be used, along with the sphere center of the charachter. what do i do with the resulting vector and the sphere center vector to find teh mirror angle of the one that i am after hitting the wall at?im not sure of trig, so im not sure if i use sin, cos or tan or atan2
I currently only use c# and directX9, in case its relivant and i didnt mention it in the post
good god no...

I'll repeat myself again. The simplest way is to use vector maths, which will then involve only dot products, as far as the exotic stuff is concerned.

"To do a Sphere(centre='C', radius = 'r') vs a Box('min', 'max'), you shall take the closest point on the box to the sphere centre, you shall then call that point 'Bcoll', then that point being the closest on the box to the sphere centre, you shall verify is that point is in the sphere, If it is not, then there is no collision, since no other point in the box can be closer thatn the closest point. If it is inside, then you have a collision. Then you will move the sphere away from 'Bcoll' so 'Bcoll' is at distance 'r' from the sphere. Then you shall reflect the velocity vector of the sphere onto the collisoin plane defined by the vector 'N' = ||SphereCentre - Bcoll||, using the mighty equation V' = V - N * (V.Dot(N)), then your enemies will be vanquished."


in code now, ....

bool Collide(CSphere& S, const CAABox& Box){    Vector Bcoll = Sphere.Centre;    if (Bcoll.x < Box.Min.x) Bcoll.x = Box.Min.x; else if (Bcoll.x > Box.Max.x) Bcoll.x = Box.Max.x;     if (Bcoll.y < Box.Min.y) Bcoll.y = Box.Min.y; else if (Bcoll.y > Box.Max.y) Bcoll.y = Box.Max.y;     if (Bcoll.z < Box.Min.z) Bcoll.z = Box.Min.z; else if (Bcoll.z > Box.Max.z) Bcoll.z = Box.Max.z;     Vector Diff = Sphere.Centre - Bcoll;    float dist2 = Diff.GetLengthSquared();    float rad2  = Sphere.radius * Sphere.radius;        // sphere too far from box and not touching, or calculation error    if (dist2 > rad2 || dist2 < 0.00001f) return false;        // the normal of collision, normalised    float dist = sqrt(dist2);    Vector N = Diff / dist;    // push sphere away so 'Bcoll' just touches the sphere    // penalty_factor make sure you don't push the sphere too hard.    const float penalty_factor = 0.3f;    Sphere.Centre += N * ((r - dist) * penalty_factor);    // 'bounce' the player on the wall    // the elasticity_factor make the player bounce more or less    const float elasticity_factor = 0.25f;    float vn = Sphere.Velocity.DotProduct(N); // impact velocity      // sphere already moving away, don't reflect or you will stick to the wall    if (vn > 0.0f) return true;    // v -= N * ((1.0f + elast) * V.Dot(N));    Sphere.Velocity -= N * ((1.0f + elasticity_factor) * vn);    return true;}


one word of warning, the sphere centre has to be outside the box, or else Bcoll will be wrong. In that case, Bcoll is still the point the closest to Sphere.Centre, but you have to calculate it differently.

same algo works for sphere sphere, anything convex.... ect....

Everything is better with Metal.

What about turning left or right? He has a velocity and a direction of the player and the nomral of a bounding box plane....what direction should he turn based on what values?

This topic is closed to new replies.

Advertisement