Need equation for converting force into normal space and back

Blitz3D Forums/Blitz3D Programming/Need equation for converting force into normal space and back

sswift(Posted 2003) [#1]
I know I could do this by creating a pivot and using aligntovector and tformvector, but I'd really like to know a mathematical way to do this.

Let's say that you have a ball strike a surface. I want this ball to have a certain amount of elasticity to it. Say 0.5, meaning, that when the ball strikes a surface, it returns half the energy.

The problem is that if you do this, then a ball rolling along a surface will stop immediately.

The solution is to dampen only the ball's velocity which is in the Y direction of the space of the surface collided with. So that horizontal motion along a surface is unaffected, but if the ball falls straight down and hits the ground the majority of the force is in the direction of the surface normal and thus is dampened.

The a surface normal epresents only one axis, the Y axis, and there is no true X or Z axis direction.

I'm thinking that I can just do something with the normal of the surface... multiply it or something with the velcoity vector in some way after adjusting it somehow, and that's all I have to do. Maybe if I inverted the values of the normal on each axis, making 0 = 1 and 1 = 0... Hm.

Well I'm not sure what to do so I thought maybe someone else had already worked this out and will know what to do here.

Any suggestions?


FlameDuck(Posted 2003) [#2]
I'm not quite sire what you're asking. Do you want to project your normal onto a vector (or vice versa), normalize a vector, or something else entirely?

Normals will always have global relative coordinates, the same is true for forces (except for forces based around entity orientation [like for example a spaceship moving "forwards" along the Z axis], in which case a TFormVector would work well). In most cases vectors and normals will already be in the same space, so all you have to do is project your force onto the normal.


Floyd(Posted 2003) [#3]
Assume V is the velocity vector and N is the normal.
N is perpendicular to the surface and has length 1.
The component of V in the direction of N is given by the dot product.

If you wanted to reduce velocity by 10% in the N direction then you would subtract:

V = V - 0.1 * (N dot V) * N ; pseudocode.

Of course, in Blitz you have to handle the x,y,z components separately:

Assume dot#, nx#, vx# etc. are all defined.

dot = nx*vx + ny*vy + nz*vz

vx = vx - 0.1*dot*nx
vy = vy - 0.1*dot*ny
vz = vz - 0.1*dot*nz


(N dot V) * N is the projection of V onto N.


(tu) sinu(Posted 2003) [#4]
are you sure your sswift and not an imposter, this seems to simple for you :)


Michael Reitzenstein(Posted 2003) [#5]
That is because sswift is a newbie.


Jeremy Alessi(Posted 2003) [#6]
Yeah, Sswift ... don't you know this already ... jeez.


sswift(Posted 2003) [#7]
Sinu:

I am very sick today and not feeling up to the task. <cough> <sniffle>

I thought I'd ask so that I'd have the answer when I feel well enough to implement a little physics code. :-)

Besides, what YOU don't know is that I OFTEN ask others for help! I just happen to ask mathematicians and physicists on IRC. There's no shame in asking for help. :-) I just happen to go to the guys who are likely to be able to best answer complex questions about physics like how lift is calculated. :-) Wouldn't be where I am with my knowledge of vectors without those guys... Though they don't seem to like helping me much. :-)

But I'm sure I could figure this out if I wasn't sick as a dog. It doesn't seem too hard a problem to me. I've just got such a headache and I'm so sore I don't have any motivation to think about math. :-)

...

Floyd:
Huh... That's weird. The code you've given me is almost identical to the code which I use to calculate and add the force in the normal direction to to the velocity vector when the ball collides with a wall.

I tried multiplying the wall normal Y component by 10% but that didn't work. :-)

Here's my collide code:

			; If the entity collided with the level, make it bounce.
			If Entity_Hit > 0 

				; Calculate bounce:

	    			; Get the normal of the surface which the entity collided with.    
					Nx# = CollisionNX(ballpos, 1)
					Ny# = CollisionNY(ballpos, 1)
					Nz# = CollisionNZ(ballpos, 1)
	
				; Compute the dot product of the entity's motion vector and the normal of the surface collided with.
					VdotN# = Vx#*Nx# + Vy#*Ny# + Vz#*Nz#
							
				; Calculate the normal force.
					NFx# = -2.0 * Nx# * VdotN#
					NFy# = -2.0 * Ny# * VdotN#
					NFz# = -2.0 * Nz# * VdotN#

				; Add the normal force to the direction vector.
					Vx# = Vx# + NFx#
					Vy# = Vy# + NFy#
					Vz# = Vz# + NFz#
									
				; Do not allow the entity to move vertically.
				;	If Vy# > 0 Then Vy# = 0
	
			EndIf


I'll test out your suggestion and see what happens. I think from looking at your code that I could just shove (1.0+springyness#) in there in place of the 2.0 and it would work like I want.

...

Testing...

...

Works great, thanks. :-)


sswift(Posted 2003) [#8]
Oh and Flameduck, the whole concept of "projecting" one vector onto another is confusing to me. I've seen a java app show how that's done once, but I just don't think it is at all intuitive that that leads to the result I was looking for. :-)

But then I never was any good at math. :-) I got an F+ in high school Algebra I and II.


Floyd(Posted 2003) [#9]
Like most of math, and programming, this becomes intuitive when you have enough experience.

Your bounce code is exactly the same idea as mine:

V = V - 2.0*(V dot N)*N

negates the N-component of V. A coefficient of -1.0 would reduce that
component to nothing. An addition -1.0 makes it negative its old value.


sswift(Posted 2003) [#10]
"A coefficient of -1.0 would reduce that
component to nothing."

Which is what I guessed would happen so I went:
V = V - (1.0 + Elasticity)*(VdotN)*N


"An addition -1.0 makes it negative its old value."

Huh? Show me the equation.


Physt(Posted 2003) [#11]
Hi Swift,

I was working on this sort of thing just before I got sick also. Not sure I'll get back to it soon so here is a link to a zip. http://www.speechchips.com/actor.zip

I have the law of reflection code for bouncing off walls but still don't have the code right for having balls rolling along inclined planes correct. I did ask a friend (CalTech Phyics Grad http://projectpluto.com) for help and here is what he said on the subject:


Anyway, here's the logic for the friction force: suppose we've
got a surface normal norm = (nx, ny, nz), and a gravity vector
running in the y direction grav = (0, 1, 0). We take their vector
cross-product to get a "sideways" vector

sideways = (sx, sy, sz) = (-nz / n, 0, -nx / n)

...where n = sqrt( nx * nx + nz * nz) is a normalizing factor, to
keep 'sideways' of unit length. n is also equal to the sine of the
angle between 'norm' and 'grav'.

Next thing to do is to vector-cross-product 'sideways' with 'norm',
thereby getting a unit vector that's in the plane of the surface,
going uphill:

uphill = sideways x norm = (-ny * nx / n, (nz * nz + nx * nx) / n, -ny * nz / n)
= (-ny * nx / n, n, -ny * nz / n)

Now we gotta multiply 'uphill' by the sine of the inclination... which,
as I mentioned a few paragraphs ago, happens to be n. So:

friction_force = uphill * n = (-ny * nx, n^2, -ny * nz)
= (-ny * nx, nx * nx + nz * nz, -ny * nz)

...which means that you can compute the force vector without having to
do square roots or other unpleasant forms of math.



It's nice to have people to ask these sorts of questions. :)

As for being sick, I hope you get well soon. I'm still sort of sick as well. I've been out of work for about 3 weeks now. I thought I had an ear infection but it turned out to be Ramsay Hunt Syndrome which causes facial paralysis, metalic taste on one side of my tounge and almost total hearing loss in my left ear. The paralysis is gone and the taste is returning to normal but the ear is still totally shot and hurts like heck. The doctor says he's optomistic about my hearing returning but I'm still waiting for some sign of improvement. Guess that's why I'm up at 2:22AM writing this. Beats rolling around in bed... Moral of the story is get help early and go to a specialist if your doctor doesn't know what something is.


Floyd(Posted 2003) [#12]

"An addition -1.0 makes it negative its old value."


Sloppy typing there, should have said an additional -1.0, i.e.
-2.0 is -1.0 and another -1.0

All I meant was that 'x=x-1*x' turns x into zero while 'x=x-2*x' turns x into -x.

Similarly,

V = V - 1.0*(V dot N)*N ; turns N component of V into zero.
V = V - 2.0*(V dot N)*N ; turns N component of V into negative of original value.


Marcelo(Posted 2003) [#13]
This code should work:

Dot# = NX * Item\SpdX + NY * Item\SpdY + NZ * Item\SpdZ
ReflectX# = NX * Dot#
ReflectY# = NY * Dot#
ReflectZ# = NZ * Dot#

; 1.0 stops bouncing
; 2.0 produces a perfect bounce (no loss of energy)
bounce# = 1.1   ; Retain only 10% of the energy

Item\SpdX = Item\SpdX - ReflectX# * bounce#
Item\SpdY = Item\SpdY - ReflectY# * bounce#
Item\SpdZ = Item\SpdZ - ReflectZ# * bounce#


Note you should add some friction code to it, or the "ball" will never stop


Floyd(Posted 2003) [#14]
With this method 1.9 would bounce and reduce the speed by 10%.

In my first post I was considering that the ball had already bounced
and we just needed to slow it down.


sswift(Posted 2003) [#15]
If you'd like to check out a demo of my game before I implemented the loss of energy code, you can get it here:

http://users.adelphia.net/~scswift/boing2.zip

I'd appreciate feedback on whether you think the ball is too easy or too difficult to control.

1. Is it's maximum speed too slow, or too fast?

2. Do you think it needs to decelerate more quickly when you change direction?

3. Do you like the ability of the ball to bounce upwards when it hits a corner, or do you think the ball should only be able to fall downwards making it seem heavier and more constricted in how it can move?

You can also press space to test out what would happen when the ball rolls over an accelerator pad.


Perturbatio(Posted 2003) [#16]
The link doesn't appear to work for me.


Rob Farley(Posted 2003) [#17]
For a horrible moment there I though we were writing the same game Sswift! I'm working on Sphere Racer 2 at the moment and have just about got the physics nailed.

I think with your thing the bounce off the walls is too violent.

Regarding the control it all feels about right, the bouncing upwards feels about right too.

The space bar thingy looks cool too.


sswift(Posted 2003) [#18]
Dr Av:
This is a game I was working on a long time ago. I'm just revisiting it at the moment. It's supposed to be a cross between super monkey ball and marble madness. There'll be gems to collect and a time limit, and probably "enemies" which move in patterns or simply move towards you when you get in range.

The wall bounce being too violent is why I was asking about how to dampen it. It's much less violent now.


Perturbatio:
Try the link again, it should work. It's possible the server was just down or something at the time. It's a bit slow to respond I notice too.


Perturbatio(Posted 2003) [#19]
been trying regularly for the last ten minutes, all I get is page cannot be displayed which is usually a DNS error.
*EDIT*
I can't even get to www.adelphia.net


sswift(Posted 2003) [#20]
http://68.168.78.29/~scswift/boing2.zip

Try that link perturbatio. Looks like your DNS server is messed up.

Also, here is a new EXE file with dampening on the bounces. Please check it out and let me know what you think about the ball control.

http://68.168.78.29/~scswift/boingexe.zip


Perturbatio(Posted 2003) [#21]
Nope, still no page.

I can get every other page I want, but yours.

*EDIT*
DNS is working since I can do a tracert to your IP and it provides me with the domain.


sswift(Posted 2003) [#22]
What ISP do you have? The only way that a direct IP address like that wouldn't work would be if your ISP was blocking it.


Perturbatio(Posted 2003) [#23]
I use Blueyonder, they're not known for blocking anything (but you never know).


Perturbatio(Posted 2003) [#24]
Another way it wouldn't work BTW is if your ISP was blocking mine (or my IP address, but I've done nothing naughty, honest).

*EDIT*

It doesn't work via LeechFTP's URL snatcher either so it isn't just my browser being weird.


sswift(Posted 2003) [#25]
What is your IP address? I can see if my ISP is blocking me from accessing it then.


Perturbatio(Posted 2003) [#26]
82.41.65.151


sswift(Posted 2003) [#27]
I called my ISP, and they're not willing to search their banned IP lists, they said it would take several days to do that, and that the only reason you'd be banned is if you'd done something illegal. They said you should contact your ISP because it would be easier for them to detect where the address is being blocked.