Jump to content
A 2021 backup has been restored. Forums are closed and work in progress. Join our Discord server for more updates! ×
SoaH City Message Board

Bumper physics (Split thread)


Recommended Posts

On a related note: It was a REALLY slow day at work yesterday so I decided to try coding simple bumper-esque collision detection routine in VB. I worked out all the geometry on paper and it works fine there, but there's some kind of quirk that prevents it from working properly in code... very frustrating. Probably missing something very obvious...


'Moving object is a circle of radius R1 located at (X1,Y1)
'Bumper object is a circle of radius R2 located at (X2,Y2)

'MinD is precalculated to be the sum of the circle radii squared,
'eliminating the need for square roots on everything...

tDist = (X1 - X2) ^ 2 + (Y1 - Y2) ^ 2

If tDist <= MinD Then

'CheckDistance moves the moving object out of the bumper
'if it somehow moved inside (as if moving too fast)
'X1 and Y1 (Moving object's center) are modified and tAng
'is assigned a value for the angle of a line drawn between object
'and bumper center. Consider it magic...

CheckDistance X1, Y1, tAng, (R1 + R2), X2, Y2


'Map vX1 and xY1 (object velocity) to rotated coordinate system

vXp1 = vX1 * Cos(tAng) + vY1 * Sin(tAng)
vYp1 = vX1 * Sin(tAng) + vY1 * Cos(tAng)


'Flip component perpendicular to the contact surface to bounce

vXp1 = -vXp1


'Reconstruct back into global coordinate system

vX1 = vXp1 * Cos(tAng) + vYp1 * Sin(tAng)
vY1 = vXp1 * Sin(tAng) + vYp1 * Cos(tAng)
End If
[/CODE]

It doesn't work as expected. If I also add "vYp1 = -vYp1" (thus flipping both rotated vectors) it [i]kinda[/i] works - it's close, but noticeably wonky.

I gotta be missing something obvious...

Edit:

http://www.smidgeindustriesltd.com/Bounce.exe

That EXE (Win32) uses the above code. Moving object's velocity and position are random and reset when it stops bouncing.

=Smidge=

Link to comment
Share on other sites

For some reason, your code is a little iffy for me to understand even though it's something I know how to do ( I must just not be staring at the Visual Basic long enough to realize it's simple ), but for the part where you talk about getting a perpendicular, wouldn't it be this:

vXp1 = -1.0/vXp1

Link to comment
Share on other sites

That would give me a line perpendicular line to the vXp1 vector, but that's not what I want. Maybe if I explained it graphically...

Start at the beginning: The moving object is the one on the right. Shown in green is the velocity vector, with vX and vY in red.

fig1.gif

In this step, I have constructed a rotated coordinate system X'/Y' (in gray) to project the current velocity vectors on to. In this pic I've also done the projection onto the X' axis (vXX', vYX' - Magenta) and combined them into the new X component, vX' (Blue)

fig2a.gif

Doing the same for vY'.

fig2b.gif

Sanity check: Reinsert the original vector (green) to verify the projection works. It does. (I realize this can be done directly, but it's all about screwing around with the angles)

fig2c.gif

Now we apply the "bounce" : mirror the "perpendicular" component.

fig3.gif

Now we project the new vectors vX' and vY' back onto the global coordinate system.

fig4.gif

Done. The Y component here is ever so slightly positive in this case and rather hard to see, but it's there.

fig5.gif

Reconstruct the new combined vector, adding gin the original for reference.

fig6.gif

Why does this work? Well, we can rotate our POV and slide the vectors to the intersection of the two objects. Add in a virtual floor tangential to the bumper (now on the bottom) and voilà:a perfectly ordinary bounce.

fig7.gif

Now that I've draw that out, I'm even MORE confused. There's no reason I can think of why this doesn't work... maybe it's something to do with VB's fucked up coordinate system (angle 0 is horizontal left to right with positive angles rotating clockwise, not counter-clockwise) but that should still be okay as long as it's consistent... I think.

=Smidge=

Link to comment
Share on other sites

The logic sounds just fine. Once I understood why you rotated the axis it's actually not that complicated of a way to do it, but still strange that it doesn't work right...

Have you tried tinkering with the angles slightly to see if it causes the result to be friendly with VB's coordinate system?

Such as throwing in a negative:

vX1 = vXp1 * Cos(tAng) - vYp1 * Sin(tAng)

vY1 = vXp1 * Sin(tAng) + vYp1 * Cos(tAng)

...or switching a Sin with a Cos.

Not the nicest way to troubleshoot, but if something ends up working, you can always figure out why it worked.

In any case, this is how I normally do this kind of stuff:

http://larkss.thisisourcorner.net/files/Bumper.zip

Link to comment
Share on other sites

EDIT: No, no... still not 100%. Damn close, though.

I think I solved it. Not only was there an error in the CheckDistance() function, which I used in a few other projects but never noticed before because it's find of self-correcting internally (two mistakes canceled each other out!) but I took a whole other approach:


tDist = (X1 - X2) ^ 2 + (Y1 - Y2) ^ 2

If tDist <= MinD Then
CheckDistance X1, Y1, tAng, (R1 + R2), X2, Y2

'Vector magnitude and angle
vMag = ((vX1 ^ 2 + vY1 ^ 2) ^ 0.5) '* BE
vAng = Atan2(vY1, vX1)

'Rotate vector angle - formula varies slightly with quadrant
If vAng > 3 * Pi / 2 Then
vAng = vAng - 2 * Abs(tAng - vAng) + Pi

ElseIf vAng > Pi Then
vAng = vAng - 2 * Abs(tAng - vAng) + Pi

ElseIf vAng > Pi / 2 Then
vAng = vAng + 2 * Abs(tAng - vAng) + Pi

Else
vAng = vAng + 2 * Abs(tAng - vAng) + Pi
End If

'Apply rotation to make new vector
vX1 = vMag * Cos(vAng)
vY1 = vMag * Sin(vAng)
End If
[/CODE]

Seems to work:

bouncy.gif

bouncy2.gif

grr...

=Smidge=

Link to comment
Share on other sites

Kinda unrelated to the problem, but:


If vAng > 3 * Pi / 2 Then
vAng = vAng - 2 * Abs(tAng - vAng) + Pi

ElseIf vAng > Pi Then
vAng = vAng - 2 * Abs(tAng - vAng) + Pi
[/CODE]

Those two seem to calculate the same result for vAng. If that's the case, can't you just trash the first If?

Infact:

[CODE]
ElseIf vAng > Pi / 2 Then
vAng = vAng + 2 * Abs(tAng - vAng) + Pi

Else
vAng = vAng + 2 * Abs(tAng - vAng) + Pi
[/CODE]

These two are the same as well, so I'd imagine you could just use a single Else with no trailing If.

It was bugging me. =[

[b]Edit:[/b]

I ported your first example of code into MMF2, and I get the same problems as you were getting. When I tried out the math manually, your axis rotation only works if the angle is a multiple of 90; anything inbetween produces incorrect results when rotated back.

[b]Edit2:[/b]

Just out of curiosity, wouldn't this approach also be effective?

bumper.png

This quick and dirty diagram shows that if you compare and get the difference of the movement angle upon impact to the angle going from the bumper to the moving object, you can then turn the X and Y speeds to a normal ( I think that's what it's called; when you combine them to a single vector speed without the angle information ) and set the speed based on the perpendicular force angle ( the red arrow ) summed with the angle difference ( indicated by the curved blue arrow ).

I'm not so great with terminology anymore since Physics class was awhile back.

Link to comment
Share on other sites

Edit: Seems I really need to stop doing this while half asleep. Anyway, isn't just bouncing off the bumper good enough for this? I don't think the games did much more calculations than this.

// Calculate the bounce vector
CVec2 vecBounce = Sonic-&gt;vecPosition - Bumper-&gt;vecPosition;
vecBounce.normalize();

// Retrieve magnitude of the speed vector
float fSpeedMag = Sonic-&gt;vecSpeed.magnitude();

// Set new speed
Sonic-&gt;vecSpeed = vecBounce * fSpeedMag

Link to comment
Share on other sites

That might be the way the game works, but that's not what I'm going for... I want realistic collisions.

I know the logic can be simplified but it's broken up that way due to tinkering. I was playing with the signs until it worked - but ultimately it still doesn't. I've also been trying to calculate the angle between the velocity vector and the center-center line using dot product but that's not working either.

So annoying :/

Edit: I think I've finally got it. A few bugs in the dot product calculation but I've been watching simulations for the past 20min and no buggy bounces seem to occur. Compiled EXE and source code here:

http://www.smidgeindustriesltd.com/geom/Bounce.zip

=Smidge=

Link to comment
Share on other sites

No buggy bounces as far as I can see too Smidge.

In fact, I happened to try out the method I suggested earlier and it works great as well. The rebound speed is a set variable as the center bumper is supposed to be....a bumper, but it's very easy to cause the colliding object's movement speed to be recycled by changing one event ( which I explain in one of the comments ).

EXE.zip"]EXE

MFA.zip"]MFA

So yeah, Hyper Emerson, you now have three different ways to achieve your bumpers. The first time I saw this topic, I honestly didn't think it would get so much attention.

Link to comment
Share on other sites

The benefit here is, IMHO, if you know the angle at the collision point you can collide accurately with an object of ANY shape. This is a very generic algorithm in that regard.

My apologies for hijacking a Sonic Worlds topic for this... Gonna see what I can do about splitting it and moving it to a new thread in the R&D forum.

=Smidge=

Link to comment
Share on other sites

In spirit of Smidge's note about the flexibility of this collision system as well as due to my abundance of boredom time, I updated my example again to show off triangles using the same collision system while still working just the same as the bumpers. I also included a "dead" bumper so that it can be seen how one would preserve the moving object's speed upon collision.

Pinball anyone? ;>

bEXE.zip"]EXE

bMFA.zip"]MFA

Link to comment
Share on other sites

That might be the way the game works, but that's not what I'm going for... I want realistic collisions.

I know the logic can be simplified but it's broken up that way due to tinkering. I was playing with the signs until it worked - but ultimately it still doesn't. I've also been trying to calculate the angle between the velocity vector and the center-center line using dot product but that's not working either.

So annoying :/

Edit: I think I've finally got it. A few bugs in the dot product calculation but I've been watching simulations for the past 20min and no buggy bounces seem to occur. Compiled EXE and source code here:

http://www.smidgeindustriesltd.com/geom/Bounce.zip

=Smidge=

Obviously judging by that picture... but we were talking about a reproduction originally. You kind of hijacked the thread and then used your super powers to flip turn the world upside down into this weird context where it looks like we are up in your junk talking about Sonic shit. Not deliberately of course, but... you know.

Don't get me wrong, your shit is cool (it always is)... but the way you started this subtopic is a little weird.

Oh, but if your ultimate goal is really realistic bumper physics, you've gotta simulate impulse since it isn't really a static collision. I wanted to contribute more than that, but sadly I couldn't find any high speed camera footage of a pinball game.

Link to comment
Share on other sites

Well a *real* pinball bumper collision is simply a "superelastic" collision. The total energy increases rather than decreases. Since the bumper itself is fixed, you can just add some appropriate value to the bouncing object's velocity and achieve exactly the same result.

And yes, I did hijack the previous thread but I split it off so we're good. The Smidge works in mysterious ways~

=Smidge=

Link to comment
Share on other sites

I'm pretty sure there is actually a noticable impulse time on a pinball bumper kind of like what you feel with a Tennis racket. That's why I wanted to find some high speed footage of it. As it is, it seems too artificial and not entirely convincing. I don't know for sure though, I might just be overwhelmed by how crazy accurate it feels in Future Pinball.

EDIT: I went ahead and moved a few posts that were more related too the other thread by Dami and myself back to the other thread.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...