Ive been adding trampolines into my jme game, and have got stuck on some math.
These trampolines act exactly like the blue stuff in portal 2. (100% efficient etc)
currently all I am doing is inverting the y component of the velocity, meaning the trampoline only works flat.
This is what I am trying to work out:
I have a vector with the velocity of the player and the surface normal vector, and need to work out the out velocity.
the only way I have thought how to calculate the output involes using loads of 2d vectors and calculating angles, which turns out to be really messy.
would be much appreiciated if someone could help me come up with a formula.
I think a few dot products can work here (and why I think they are one of the most magic of vector operations). Just need to rework the problem a bit.
First, flip your inVelocity to point out from the surface…
flippedVelocity = inVelocity.multLocal(-1)
Now you have a normal pointing out of 0,0,0 and an inVelocity pointing out of 0,0,0 and we just need to reflect it. If you imagine, there is a vector we need to find that stretches from the tip of inVelocity over to the normal vector “line”. If we find this extra triangle side then we can find the tip of the reflected vector simply by reversing it. But we need to know where along the normal vector the unknown point is…
Dot product to the rescue.
float projected = normal.dot(flippedVelocity);
v1 = normal.mult(projected);
v2 = flippedVelocity.subtract(v1);
Now we have found all of the parts of the right triangle. v1 is the base leg, and v2 is the vector extending from v1… the other leg of the triangle. The flipped inVelocity is the hypotenuse.
If we flip v2: v2.multLocal(-1)
And add it back to v1:
reflected = v1.add(v2)
We have the reflected velocity… because we flipped the triangle.
At least that’s my back-of-napkin level solution. Hopefully I explained it well enough not to require pictures.
The key is to remember that the dot product of some unit vector and some other vector will tell you the cosine of the triangle formed between those two vectors… scaled to the non-unit vector. (ie: if both vectors are unit vectors then you get the actual cosine of the angle between them presuming that in v1.dot(v2) v1 is the base and v2 is the hypotenuse)
Mathematically speaking you need to define a plane for the surface and then reflect the incoming vector in that plane.
I believe the JME3 plane classes have some reflection tools built in although I could be wrong, it’s not something I’ve had a use for yet.
im using this formula:
Vout = Vin.negate().add( normal.mult( normal.dot(Vin.negate()) ) .add(Vin) .mult(2) )
which is what you did but in a slightly different order
It seems to be working perfectly.
Thanks very much for explaining it to me
Maybe you transcribed something incorrectly or there is something I’m missing…
But I can’t see how -Vin + anything +Vin will give you anything but just “anything” by itself.
its just rearranged a bit(i think correctly).
v1 = normal x (normal.dot(-Vin))
v2 = v1 - - Vin = v1 + Vin
Vout = -Vin + (2 x v2)
I misread the parenthesis placement.