Page 1 of 1
CELX: Finding a moving observer's current vector.
Posted: 05.03.2008, 15:51
by buggs_moran
In Celx, how do you make a vector out of your current position and speed (no object selected) in celx? I do not want to use focus, center or any of the like...
For instance:
I am traveling in space, in general, no aim, no destination, just travelling. Then, suddenly, I have an urge to go to Neptune.
- I know how to get my current position (call it obsPos).
- I know how to get Neptune's position. (call it plaPos).
- The vector (vtoPlanet) from obsPos to plaPos is obsPos-plaPos.
- The vector (vcurrent) is what I need to know how to do.
From there I plan to
- find the angle between the vectors. acos(vcurrent * vtoPlanet)
- find the upvector, (vtoPlanet ^ vcurrent)
- and turn towards the planet with a rotation
--------local yaw=celestia:newrotation(upvector, angle)
--------celestia:getobserver():rotate(yaw)
Re: CELX: Finding a moving observer's current vector.
Posted: 05.03.2008, 16:04
by Vincent
buggs_moran wrote:The vector (vcurrent) is what I need to know how to do.
I'm not sure about what you mean by
vcurrent, but observer:getorientation() will return the observer's orientation as a quaternion (x, y, z, w):
Code: Select all
obs = celestia:getobserver()
rot = obs:getorientation()
Then you should be able to get the (x, y, z) vector using:
Posted: 05.03.2008, 17:17
by chris
The only way that I think you can get the observer velocity is to take the difference in position between two subsequent frames. More or less this:
Code: Select all
p0 = obs:getposition()
t0 = celestia:gettime()
wait(0)
p1 = obs:getposition()
t1 = celestia:gettime()
v = (p1 - p0) / (t1 - t0)
Now, calling an extra wait to compute the velocity isn't really desirable. You should probably add the code to save the current position and time to the place you're calling wait() now.
--Chris
Posted: 06.03.2008, 13:21
by buggs_moran
Thank you Vincent and Chris.
It is not working the way I had hoped, but you information is useful. I will have to keep trying. I get very strange angles that do not point in the direction I expect. I am sure I am missing something fundamental. I will keep plugging away...
Posted: 09.03.2008, 21:23
by buggs_moran
Okay, I am very confused.
Shouldn't the following code go to my starting position then,
1) get the observer position
2) get the position of the object, planets[i] (from a table)
3) get vector x,y,z for observer and normalize it
4) get a vector from the observer to the object, planets[i] and normalize it
5) find the angle between the vectors
6) find the cross product of the vectors and therefore the "up" vector between 3 & 4
7) turn to the object, planets[i]
or am I being WAY too simplistic? I get the feeling this is the case.
Code: Select all
obs = celestia:getobserver()
sol = celestia:find("Sol")
celestia:select(sol)
obs:gotolonglat(sol, math.rad(45), math.rad(0), 1e10)
wait (5.0)
obsPosition = obs:getposition()
objPosition = planets[i]:getposition()
obsrot = obs:getorientation()
v_obs = obsrot:imag()
v_obsn = v_obs:normalize()
v_obj = objPosition - obsPosition
v_objn = v_obj:normalize()
angle = math.acos(v_objn * v_obsn)
upvector = (v_objn ^ v_obsn)
local quat=celestia:newrotation(upvector, angle/50)
for i=1,50 do
celestia:getobserver():rotate(quat)
wait(0)
end--for
Posted: 12.03.2008, 02:07
by buggs_moran
I am just bumping this in case it got missed... Sorry if it aggravates anyone...
Posted: 12.03.2008, 06:49
by Vincent
buggs_moran wrote:I am just bumping this in case it got missed... Sorry if it aggravates anyone...
Buggs,
You can also simply get
v_obsn using:
Code: Select all
v_obs = sol:getposition() - obsPosition
v_obsn = v_obs:normalize()
Or more generally:
Code: Select all
v_obs = planet[i-1]:getposition() - obsPosition
v_obsn = v_obs:normalize()
I'm not sure this will fix your problem, though.
Posted: 12.03.2008, 09:48
by buggs_moran
The problem with both of those is that it will not give me the angle between my current direction and the object I want to go to...
Posted: 12.03.2008, 10:58
by Vincent
buggs_moran wrote:The problem with both of those is that it will not give me the angle between my current direction and the object I want to go to...
What about defining upvector as the upvector
for observer?
Code: Select all
upvector = celestia:newvector(0, -1, 0)
Posted: 12.03.2008, 11:39
by Vincent
Buggs,
Another alternative would be to convert obsPosition, objPosition and solPosition from universal coodinates to the observer's local frame coordinates:
Code: Select all
obsPosition = obs:getposition()
objPosition = obj:getposition()
solPosition = sol:getposition()
obs_frame = celestia:newframe("observer", sol)
obsPos = obs_frame:to(obsPosition)
objPos = obs_frame:to(objPosition)
solPos = obs_frame:to(solPosition)
v_obs = solPos - obsPos
v_obsn = v_obs:normalize()
v_obj = objPos - obsPos
v_objn = v_obj:normalize()
angle = math.acos(v_objn * v_obsn)
Then, you could effectively define upvector as:
Posted: 13.03.2008, 00:24
by buggs_moran
But the problem is that I do not want to reference another body like the Sun... I am essentially trying to duplicate the "center" command, without using the center command...
Posted: 13.03.2008, 12:00
by Vincent
buggs_moran wrote:But the problem is that I do not want to reference another body like the Sun... I am essentially trying to duplicate the "center" command, without using the center command...
Well, here's another way to do that:
Code: Select all
obsPosition = obs:getposition()
objPosition = obj:getposition()
d_obj = objPosition:distanceto(obsPosition)
obs:gotodistance(obj, d_obj)
wait(3)