Some questions about 2D polygon collision response - math

Hey so after reading this article I've been left with a few questions I hope to resolve here.
My understanding is that the goal of any multi-dimensional collision response is to convert it to a 1D collision be putting the bodies on some kind of shared axis. I've deduced from the article that the steps to responding to a 2d collision between 2 polygons is to
First find the velocity vector of each bodies collision point
Find relative velocity based on each collision point's velocity (see question 1)
Factor in how much of that velocity is along the the "force transfer line (see question 2)"
(which is the only velocity that matters for the collision)
Factor in elasticity
Factor in mass
Find impulse/ new linear velocity based on 2-4
Finally figure out new angular velocity by figuring out how much of the impulse is "rotating around" each object's CM (which is what determines angular acceleration)
All these steps basically figure out how much velocity each point is coming at the other with after each velocity is translated to a new 1D coordinate system, right?
Question 1: The article says relative velocity is meant to find and expression for the velocity with which the colliding points are approaching each other, but to me it seems as though is simply the vector of
CM 1 -> CM 2, with magnitude based on each point's velocity. I don't understand the reasoning behind even including the CMs in the calculations since it is the points colliding, not the CMs. Also, I like visualizing things, so how does relative velocity translate geometrically, and how does it work toward the goal of getting a 1D collision problem.
Question 2: The article states that the only force during the collision is in the direction perpendicular to the impacted edge, but how was this decided? Also how can they're only be force in one direction when each body is supposed to end up bouncing off in 2 different directions.

"All these steps basically figure out how much velocity each point is coming at the other with after each velocity is translated to a new 1D coordinate system, right?"
That seems like a pretty good description of steps 1 and 2.
"Question 1: The article says relative velocity is meant to find and expression for the velocity with which the colliding points are approaching each other, but to me it seems as though is simply the vector of CM 1 -> CM 2, with magnitude based on each point's velocity."
No, imagine both CMs almost stationary, but one rectangle rotating and striking the other. The relative velocity of the colliding points will be almost perpendicular to the displacement vector between CM1 and CM2.
"...How does relative velocity translate geometrically?"
Zoom in on the site of collision, just before impact. If you are standing on the collision point of one body, you see the collision point on the other point approaching you with a certain velocity (in your frame, the one in which you are standing still).
"...And how does it work toward the goal of getting a 1D collision problem?"
At the site of collision, it is a 1D collision problem.
"Question 2: The article states that the only force during the collision is in the direction perpendicular to the impacted edge, but how was this decided?"
It looks like an arbitrary decision to make the surfaces slippery, in order to make the problem easier to solve.
"Also how can [there] only be force in one direction when each body is supposed to end up bouncing off in 2 different directions."
Each body experiences a force in one direction. It departs in a certain direction, rotating with a certain angular velocity. I can't parse the rest of the question.

Related

Angular Velocity to rotate Heading towards Point

I have a 3D point in space, and I need to know how to pitch/yaw/roll my current heading (in the form of a 3d unit vector) to face a point. I am familiar with quaternions and rotation matrices, and I know how to represent the total rotation necessary to get my desired answer.
However, I only have control over pitch, yaw, and roll velocities (I can 'instantaneously' set their respective angular velocities), and only occasional updates on my new orientation (once every second or so). The end goal is to have some sort of PID controller (or three separates ones, but I suspect it won't work like that) controlling my current orientation. the end effect would be a slow (and hopefully convergent) wobble towards a steady state in the direction of my destination.
I have no idea how to convert the current desired quaternion/rotation matrix into a set of pitch-yaw-roll angular velocities (some sort of quaternion derivative or something?). I'm not even sure what to search for. I'm also uncertain how to apply a PID controller to this system, because I suspect there will need to be one controller for the trio as opposed to treating them each independently (although intuitively I feel this should be possible). Can anyone offer any guidance?
As a side note, if there is a solution that just involves a duo (pitch/yaw, roll/pitch, etc), then that works just fine too. I should only need 2 rotational degrees of freedom for this, but that is further from a realm that I am familiar with so I was less confident forming the question around it.
First take a look if your problem can be solved using quaternion SLERP [1], which can let you specify a scalar between 0 and 1 as the control to move from q1-->q2.
If you still need to control using the angular rotations then you can calculate the error quaternion as Nico Schertler suggested.
From that error quaternion you can use the derivative property of the quaternion (Section 4 of http://www.ecsutton.ece.ufl.edu/ens/handouts/quaternions.pdf [2]) to work out the angular rates required.
I'm pretty sure that will work, but if it does not you can also look at using the SLERP derivative (eq. 23 of http://www.geometrictools.com/Documentation/Quaternions.pdf [3]) and equating that to the Right-Hand-Side of the equation in source [2] to again get angular rates. The disadvantage to this is that you need code implementations for the quaternion exponentiation and logarithm operations.

Finding the normal between a cylinder and a triangle

I have a pretty rudimentary physics engine in the game I'm working on, between moving, cylindrical characters, and static meshes made of triangles. The intended behavior is for characters to slide across surfaces, and in most cases, it works fine. But the engine doesn't discriminate between a head-on collision and a glancing collision.
I'm not entirely sure what information I could give that would be helpful. I'm looking for a mathematical solution, at any rate, a method to determine the 'angle of contact' between an arbitrary cylinder and triangle. My instincts, or whatever, tell me that I need to find the point of contact between the triangle and the cylinder, then determine whether that point is within the triangle (Using the triangle's regular normal) or along one of its edges (Using the angle between the point of contact and some point on the cylinder, I'm not sure which.), but I'm sure there's a better solution.
As requested, here's a couple of examples. In this first image, a cylinder travels downwards towards a triangle (In this example, the triangle is vertical, simplified to a line.) I project the velocity vector onto the plane of the triangle, using the formula Vf = V - N * (dot(V,N)). This is the intended behavior for this type of collision.
In this image, the cylinder's axis is parallel with the normal of the triangle. Under the current implementation, Vf is still determined using the triangle's natural normal, which would cause the cylinder to begin moving vertically. Under intended behavior, N would be perpendicular to the colliding edge of the triangle.
But these are just the two extremes of collision. There are going to be a bunch of in-betweens, so I need a more arbitrary solution.
This is my attempt at a more 3D example. I apologize for the poor perspective. The bottom-most vertex in this triangle is closer to the 'camera'. The point of collision between the cylinder and the triangle is marked by the red X. Under intended behavior, if the cylinder was moving directly away from the camera, it would slide to the left, along the length of the triangle's edge. No vertical movement would be imparted, as the point of contact is along the cylinder's, uh, tube section, rather than the caps.
Under current behavior, the triangle's normal is used. The cylinder would be pushed upwards, as though sliding across the face of the triangle, while doing little to prevent movement into the triangle.
I understand that this is a difficult request, so I appreciate the suggestions made to help refine my question.
What you're looking for is probably an edge collision detector. In rigid body collision systems, there are usually two types of collisions: surface collisions (for colliding with things that have a regular surface normal, where the reaction normal can be computed easily, as you pointed out, by processing A velocity vs B surface normal), and edge collisions (where the A body hits the edge of B body, be it box, triangle or anything else). In this case, the matter is more complicated, because, obviously, edge is not a surface, and thus you can't calculate it's normal at all. Usually, it's approximated one way or another - you can for example assume that, for triangle mesh, the edge normal is the average between normals of the two edge triangle's. There are also other methods to deal with it, some discussed here:
https://code.google.com/p/bullet/downloads/detail?name=CEDEC2011_ErwinCoumans.pdf&can=2&q=
Usually, there's an edge processing threshold value, if a collision occurred in the radius of this value, it's considered an edge collision, and processed differently.
See the examples here:
http://www.wildbunny.co.uk/blog/2012/10/31/2d-polygonal-collision-detection-and-internal-edges/
Googling "internal edge collision" and learning about rigid body collisions/dynamics in general will help you understand and solve this problem by yourself.

Rectangle physics in 2D. Am I doing this right?

I'm writing a 2D game, in which I would like to have crate-like objects. These objects would move around, like real crates do. I have a hypothetical idea of how I would like to achieve that:
Basically I'd store the boxes' corners' coordinates with their force and velocity unit vectors, and in every update I'd basically do the following steps:
1. Apply the forces(gravity, from collisions, etc..) accordingly.
2. Modify velocity vector based on the force.
3. Move every corner of the box, like so:
4. I repeat nr 3. for every corner, so I get the real movement of the cube.
My questions are: Is this approach heading in the right direction? Is this theory even correct? If not, what would be the correct way to move a box around based on vectors in a 2D environment?
Just to clarify: I'm only dragging corner "A" in the picture, but I want to repeat the dragging for every other corner, with their own vectors. By "dragging" I mean the algorithm I just stated.
Keeping each corner's coordinate and speed makes no sense as you would be storing lots of redundant information. Boxes are rigid objects, which means that there are constraints that must be satisfied at any time instant, namely the distance between any two given corners is fixed. This also translates to a constraint that links the velocities of all four corners and so they are not independent values. With rigid bodies the movement of any point is the sum of two independent movements - the linear movement of the centre of mass (CM) and the rotation around a fixed axis - often, but not always, chosen to be the one that goes through the CM. Hence you only need to store the position and the velocity of the crate's CM (which coincides with the geometric centre of the crate) as well as the angle of rotation and the rate of rotation around the CM.
As to the motion, the gravity field is a constant vector field and hence cannot induce rotation in symmetric objects like those rectangular crates. Instead it only produces accelerated vertical motion of the CM. This is also what happens due to all external forces - one has to take their vector sum and apply it to the CM. Only external forces whose direction does not go through the CM give torque and so cause rotation. Such forces are any external pushes/pulls or reaction forces that arise when crates collide with each other or hit the ground / a wall. Computing torque due to external forces is easy but computing reaction forces could be quite involving process because of the constrained dynamics that has to be employed. Once the torque has been computed, one has to divide it by the moment of inertia of the create in order to get the angular acceleration. Often it is more convenient to use another axis and not the one that goes through the CM - Steiner's theorem can be employed in this case in order to compute the moment of inertia around that other axis.
To summarise:
all forces, acting on the create, are first added together (as vectors) and the resultant force (divided by the mass of the create) determines the linear acceleration of the CM;
the torque of all forces is computed and then used to determine the angular acceleration around a given axis.
See here for some sample problems of rigid body motion and how the physics is actually worked out.
Given your algorithm, if by "velocity vector" you actually mean "the velocity of CM", then 1 would be correct - all corners move in the same direction (the linear motion of the CM). But 2 would not be always correct - the proper angle of rotation would depend on the time the torque was applied (e.g. the simulation timestep), and one has to take into account that the lever arm length changes in between as the crate rotates.

Calculating thrusts for offset thruster positions given arbitrary thrusters at arbitrary position around a mass

I've had a bit of a sniff around google for a solution but I believe my terminology is wrong, so bear with me here.
I'm working on a simple game where people can build simplistic spaceships and place thrusters willy nilly over the space ship.
Let's call say my space ship's center of mass is V.
The space ship has an arbitrary number of thrusters at arbitrary positions with arbitrary thrust direction vectors with an arbitrary clamp.
I have an input angular velocity vector (angle/axis notation) and world velocity (vector) which i wish the ship to "go" at.
How would I calculate the the ideal thrust for each of the thrusters for the ship to accelerate to the desired velocities?
My current solution works well for uniformly placed thrusters. Essentially what I do is just dot the desired velocity by the thrusters normal for the linear velocity. While for the angular velocity I just cross the angular velocity by the thrusters position and dot the resulting offset velocity by the thrusters normal. Of course if there's any thrusters that do not have a mirror image on the opposite side of the center of mass it'll result in an undesired force.
Like I said, I think it should be a fairly well documented problem but I might just be looking for the wrong terminology.
I think you can break this down into two parts. The first is deciding what your acceleration should be each frame, based on your current and desired velocities. A simple rule for this
acceleration = k * (desired velocity - current velocity)
where k is a constant that determines how "responsive" the system is. In order words, if you're going too slow, speed up (positive acceleration), and if you're going too fast, slow down (negative acceleration).
The second part is a bit harder to visualize; you have to figure out which combination of thrusters gives you the desired accelerations. Let's call c_i the amount that each thruster thrusts. You want to solve a system of coupled equations
sum( c_i * thrust_i ) = mass * linear acceleration
sum( c_i * thrust_i X position_i) = moment of interia * angular acceleration
where X is the cross produxt. My physics might be a bit off, but I think that's right.
That's an equation of 6 equations (in 3D) and N unknowns where N is the number of thusters, but you've got the additional constraint that c_i > 0 (assuming the thrusters can't push backwards).
That's a tricky problem, but you should be able to set it up as a LCP and get an answer using the Projected Gauss Seidel method. You don't need to get the exact answer, just something close, since you'll be solving it again for slightly different values on the next frame.
I hope that helps...

Simple Problem - Velocity and Collisions

Okay I'm working on a Space sim and as most space sims I need to work out where the opponents ship will be (the 3d position) when my bullet reaches it. How do I calculate this from the velocity that bullets travel at and the velocity of the opponents ship?
Calculate the relative velocity vector between him and yourself: this could be considered his movement if you were standing still. Calculate his relative distance vector. Now you know that he is already D away and is moving V each time unit. You have V' to calculate, and you know it's length but not it's direction.
Now you are constructing a triangle with these two constraints, his V and your bullet's V'. In two dimensions it'd look like:
Dx+Vx*t = V'x*t
Dy+Vy*t = V'y*t
V'x^2 + V'y^2 = C^2
Which simplifies to:
(Dx/t+Vx)^2 + (Dy/t+Vx)^2 = C^2
And you can use the quadratic formula to solve that. You can apply this technique in three dimensions similarly. There are other ways to solve this, but this is just simple algebra instead of vector calculus.
Collision Detection by Kurt Miller
http://www.gamespp.com/algorithms/collisionDetection.html
Add the negative velocity of the ship to the bullet, so that only the bullet moves. Then calculate the intersection of the ship's shape and the line along which the bullet travels (*pos --> pos + vel * dt*).
The question probably shouldn't be "where the ship will be when the bullet hits it," but IF the bullet hits it. Assuming linear trajectory and constant velocity, calculate the intersection of the two vectors, one representing the projectile path and another representing that of the ship. You can then determine the time that each object (ship and bullet) reach that point by dividing the distance from the original position to the intersection position by the velocity of each. If the times match, you have a collision and the location at which it occurs.
If you need more precise collision detection, you can use something like a simple BSP tree which will give you not only a fast way to determine collisions, but what surface the collision occurred on and, if handled correctly, the exact 3d location of the collision. However, it can be challenging to maintain such a tree in a dynamic environment.

Resources