Movement arround a sphere

Started by
5 comments, last by Chrstn Lck 8 years, 8 months ago

Hello,

for my game, I want to make a character move between two points on a sphere. Each point is represented as Vector3 in World Space. I know where the Center of the Sphere is, but I don't know the math, to calculate the movment. I found this Thread here: http://www.gamedev.net/topic/520395-movement-on-sphere-surface but I couldnt really get it to work. My units just float in a straight line. I wonder if anybody here could help me out. Im really not that good in math but I would love to get this to work.

Thank you very much for your help.

Advertisement
A) The easiest way, although with non-constant speed: Interpolate the positions directly in a linear fashion but re-scale the vector to the appropriate length. This works best if the start and end point are relatively close. This method fails miserably if start and end position are at most on opposites sides of the sphere.
With start position s and end position e, both in world co-ordinates, compute their counterparts relative to sphere center c as

s' := s - c

e' := e - c

Compute the difference vector from start to end
d' := e' - s'
Interpolate the difference vector in N steps to get the linear in-between positions
b'n := s' + d' * n / N w/ 0<= n <= N
Rescale the vector to a length equal to the radius r of the sphere
p'n := b'n / | b'n | * r
Eventually transform the current position back into world space
pn := p'n + c

B) Utilizing a rotation, getting constant speed: With the start and end position given as vectors relative to the sphere's origin, compute the axis of rotation as cross-product of the 2 vectors and the difference angle from the dot-product formula. Then interpolate the angle in as many steps as you want, and use it together with the axis to build a rotation matrix. Apply the rotation onto the start position vector. This method fails (as all do more or less) if start and end position are at most on opposites sides of the sphere.

With start position s and end position e, both in world co-ordinates, compute their counterparts relative to sphere center c as

s' := s - c

e' := e - c

Compute the axis of rotation r as normalized cross-product
r := ( s' x e' ) / | s' x e' |
Compute the angle of rotation a from the dot-product
a := arccos( ( s' . e' ) / ( | s' | * | e' | ) )
Interpolate the angle in N steps to get the in-between angle b
bn := a * n / N w/ 0<= n <= N
Compute the rotation matrix R from axis and in-between angle
Rn( r, bn )
Apply the rotation onto the start position to yield in the current position
p'n := Rn * s'
Eventually transform the current position back into world space
pn := p'n + c
Another way (as shown in the cited post in the OP) is to convert the positions into quaternions and using nlerp or slerp, but that is IMHO less clear from a mathematical point of view.

Hello,

thank you very much! I am trying to implement solution b, but have a question about this part:

Compute the angle of rotation a from the dot-product
a := arccos( ( s' . e' ) / ( | s' | * | e' | ) )
What exactly does | s' | * | e' | mean? Do you mean normalized s' and e'. If so, how do I devide a scalar by a vector? s' . e' should result in a scalar value, right?


What exactly does | s' | * | e' | mean?

I means the product of the lengthes (a.k.a. absolute value, norm) of the vector s' and e', resp. A vector length is computed as square root of the sum of squared co-ordinate values:

| v | := sqrt( vx2 + vy2 + vz2 )

The result is a scalar, so division is okay (as long as the length is not zero, i.e. the vector vanishes, of course).

Thanks again. I got it to a point, at where my characters move at which what seems a constant speed. They stick to the surface, however, they never reach the target point.

What would be a good way to determine b

bn := a * n / N w/ 0<= n <= N
What I tried is something like this:
bn := a * speed * deltaTime
but I am not sure, if this is a correct way.

The simple way I suggested so far was to choose N as the amount of steps that should pass until reaching the end position. Then n (i.e. the lower case letter) iterates from 0 to N, so that at n==0 the start position is valid and at n==N the end position is reached. Notice that during this run the s' and e' should be constant and bn is absolute, so do not compute it in increments. However, this method does not work well with a variable time step.

Another method, this time one that considers a speed and a variable time step if you want to do so, would be to compute the arc length from s' to e' as

l := r * a / ( 2pi )

where r is the radius of the sphere and a the angle, both as given in the previous post. Then for a given constant speed s, the time T needed from s' to e' should be

T := l / s

For an elapsed delta time t, the corresponding delta angle would be

a * t / T

This one could be accumulated to result in the in-between angle like so

bn := bn-1 + a * tn / T w/ the initial in-between angle b-1 := 0

where tn is the delta time from step to step.

This did the trick. Works pretty good now. Thanks a bunch :)

This topic is closed to new replies.

Advertisement