![]() |
|
[Math] Elasticity/Deflection |
ngiacomelli
Member #5,114
October 2004
|
Quite a few questions here. I'm looking for a very simple way to demonstrate elasticity! Basically, I have a line with two points. I have a spherical object. I want to check the line for a collision with this spherical object. After that, I need a way to find the angle of deflection... and update the spherical objects speed/direction accordingly. {"name":"590377","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/7\/f7433584382862f02fff33c41ec27b86.png","w":339,"h":235,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/7\/f7433584382862f02fff33c41ec27b86"}
|
DanielH
Member #934
January 2001
![]() |
You can use these 3d equations with 2D with some minor adjustments; Point1 = ( x1, y1, 0 ); Normal to Line: normal = ( Point2 - Point3 ).crossProduct( Point2 - Point1 ); normal = normal / normal.length; // normalize Distance to Line: (distance is signed, neg means other side ) distance = normal.dotProduct( spherePos - ArbitraryPointOnLine ); To be a hit then distance is less than sphereRadius. if ( distance < sphereRadius ) { spherePos = spherePos + Dir + this->normal * 2.0 * ( sphereRadius - distance ); }
|
Zaphos
Member #1,468
August 2001
|
Quote: normal = ( Point2 - Point3 ).crossProduct( Point2 - Point1 ); For reference (since a cross product for 2D seems a bit silly), you can find the normal direction of a 2D line like this: Say your line is p1 to p2, and it's direction is d = (p2 - p1) = (dx, dy). Then the normal direction is just (-dy, dx). And the normalized normal, as in the 3D case, may be found by dividing the normal direction by its magnitude. Quote: Point3 = ( x2, y2, -5 ); There should be no need to keep around that Point3 variable, or use 3D math functions -- functions that only operate on 2D vectors will work just fine. Quote: distance = normal.dotProduct( spherePos - ArbitraryPointOnLine ); Note that to detect a hit on a line segment, which is what it looks like you might be talking about, you also would want to do another dot product to find how far along the line segment the circle lies, and you'd want to do two distance tests against the line segment's endpoints. Quote: After that, I need a way to find the angle of deflection... and update the spherical objects speed/direction accordingly.
You probably don't want to use an angle of deflection, or a direction vector, or a speed value. Just track velocity. To adjust the velocity in response to a collision, do something like this: I'll note that I really have no idea what math you do or don't understand, so ... if anything doesn't make sense: sorry! Ask for clarifications as needed.
|
ngiacomelli
Member #5,114
October 2004
|
Quote:
I'll note that I really have no idea what math you do or don't understand, so ... if anything doesn't make sense: sorry! Ask for clarifications as needed. I'm not so hot when it comes to number work. I understand that the dot product is the result of adding two vectors together. I'm not entirely sure why DanielH is using 3d equations, but I assume I can just remove the references to point3. I'm definately going to need my hand held for a little. I'm not even sure how I would go about writing the routines to calculate the dot product or cross product. I don't like to just copy and paste code. So if anyone's willing to (try) and explain this to me, that'd be wonderful.
|
DanielH
Member #934
January 2001
![]() |
Quote: I'm not entirely sure why DanielH is using 3d equations That's all I've been working with for the past few weeks. |
Zaphos
Member #1,468
August 2001
|
Quote: I understand that the dot product is the result of adding two vectors together. Okay, so for notation I'll refer to a vector as if it had this structure: struct vector { float x; float y; }; The dot product is an operation that takes two vectors and returns a scalar (single number). It takes the components of the vectors, multiplies them together, then sums the results. float dot_product(vector a, vector b) { return a.x * b.x + a.y * b.y; }
Abstractly, the dot product is useful because of one interesting identity: dot_product(v, n) = length(v) * length(n) * cos(theta), where theta is the angle between vectors v and n. In our case what we want is really the length(velocity) * cos(theta). We get this out of dot_product(velocity, normal) by ensuring the normal vector is 'normalized' -- has length(n) == 1. Now, think back to your collision example. Let's look at a picture:
Is this making sense?
|
ngiacomelli
Member #5,114
October 2004
|
I wrote the following code:
And got these results: l1: 141.421356 | l2: 200.000000 | l3: 141.421356 Am I on the right track, here? EDIT: Just saw the new post, reading!
|
Zaphos
Member #1,468
August 2001
|
Quote: return sqrt( p1.x * p2.x + p1.y * p2.y ); That's not a dot product. That's the square root of a dot product. Quote: len2 = dotProduct( p1, p2 ); I'm not sure why you think that's len2. Did you mean dotProduct( p2, p2 )? Quote: Am I on the right track, here? Well, I have no idea what you're trying to do, here. The dot product can give the squared magnitude of a vector, if you take the dot product of a vector and itself, because then the cos is equal to 1. But that's not really how you're going to be using the dot product for collision detection and response. edit: Oh ... was that code in response to DanielH's now-mysteriously-absent post?
|
ngiacomelli
Member #5,114
October 2004
|
I was just converting DanielH's equations to code, initially. I'll have to read through your post. I'm terrible when it comes to math. This will take me a while.
|
DanielH
Member #934
January 2001
![]() |
I goofed and erased my goof. I was hoping it wasn't viewed before I erased it. |
|