Page 1 of 1

problem turning observer precise angle and axis

Posted: 11.04.2011, 01:37
by ChrisA
Hi celestians,

First a little background.

I am attempting to create a full dome planetarium movie using celestia. In order to achieve a 180 degree field of view I need to have four different views of each scene (front, up, left and right). It does not seem to be possible to achieve this using celestia's in built movie capture function because slight timing differences make it difficult to allign the various parts of each scene.

I have written a celx script that saves a series of screen shots which I can successfully process into a full dome movie. This part of the project is working well.

My problem.

In one scene I want the observer's orientation to move from the earth to the moon. I have found the vectors from obs to earth and from obs to moon and found the angle between them. I have then found the cross product of that angle and used it as the axis for the turn. I then divide the angle by the number of frames required and use this in a loop to take the screen shots. The problem is that it dosn't work. The observer turns but the axis is wrong. Also the axis of the turn alters depending on the location (latitude and longitude) above earth. I think the problem must relate to my poor understanding of reference frames but I have tried all I can think of and seem to be getting nowhere.

I have attached a section of script that shows the problem. Any help would be greatly appreciated.

Code: Select all

function rotate_obs(rotangle, rotaxis, rottime)
   -- Rotangle is the angle between origin and target
   -- Rotaxis is the cross product of the vectors obs to origin and obs to target
   -- Rottime is the duration of the rotation in seconds
   local obs = celestia:getobserver()
   -- Rotsteps sets number of steps for required frame rate
   local rotsteps = 24 * rottime
   local stepangle=rotangle/rotsteps
   local rot = celestia:newrotation(rotaxis, stepangle)
   local rotsteptime = rottime/rotsteps
   for i = 1, rotsteps do
      obs:rotate(rot)
      wait(rotsteptime)
   end
end

uly_to_km = 9460730.4725808
celestia:settime(2455505.77)
celestia:settimescale(0)
obs=celestia:getobserver()
sun=celestia:find("Sol")
earth = celestia:find("Sol/Earth")
moon= celestia:find("Sol/Earth/Moon")
obs:synchronous(earth)
alt=12000+earth:radius()
longitude=math.rad(147)
latitude=math.rad(-41)
obs:gotolonglat(earth,longitude,latitude,alt,1)
wait(2)
obspos=obs:getposition()
moonpos=moon:getposition()
earthpos=earth:getposition()
orig_vec=obspos-earthpos
orig_vecn=orig_vec:normalize()
target_vec=obspos-moonpos
target_vecn=target_vec:normalize()
rotation_angle=math.acos(orig_vecn * target_vecn)
axis_vector=(target_vecn ^ orig_vecn)
rotationtime=5
celestia:setrenderflags{markers = true}
celestia:mark(moon)
rotate_obs(rotation_angle,axis_vector,rotationtime)
wait(10)


BTW, I am using Celestia Portable 1.6.0

Thanks

Re: problem turning observer precise angle and axis

Posted: 14.04.2011, 18:56
by Marco Klunder
Hello ChrisA,

Although I do not completely understand your problem,
- Is it about the exact angle/axis setting?
- Is it about a smooth rotation from centered Earth to centered Moon?
- Is it about saving the scene (in a later phase) for each op the 24 steps during rotation?
- ...
probebly here are a few sugestions to look at, to solve your issue/problem:

Examine the example and the usage of the rotation:slerp() method: http://en.wikibooks.org/wiki/Celestia/Celx_Scripting/CELX_Lua_Methods/Celx_rotation#slerp.
The example exlains how to exactly orient on the postion halfway the Earth-Moon from a position somewhere in space.
In your case, probably putting this slerp() method in a loop with percentages rolling from 0 to 1 in very small steps may result in an exact smooth transition from a view on earth to a view on the Moon.

It is also possible to divide the percentages in 24 steps (or better 25), having the rotation for each step you probably want to save, by using that rotation in the observer:rotate() or observer:setorientation() method (no smooth transition).

The observer:goto(table) method http://en.wikibooks.org/wiki/Celestia/Celx_Scripting/CELX_Lua_Methods/Celx_observer#goto_.28table.29 also has the ability to smoothly change postion and/or orrientation in the "universal" coordinate system. In your example, begin and end postion are the same and the begin orientation is towards the Earth and the end orientation towards the taget position, (in your case) the moon.

Hope this and the WIKI examples may help you further...

Marco

Re: problem turning observer precise angle and axis

Posted: 15.04.2011, 06:58
by ChrisA
Hello Marco,
Thanks for your reply.

To clarify my problem,
- Is it about the exact angle/axis setting?
Yes. I think I have the angle correct, but at the completion of the rotation the observer is not centered on the moon. The moon may or may not be visible, dependant on the observers geographic position above the earth.

- Is it about a smooth rotation from centered Earth to centered Moon?
No. I do not need the rotation to be smooth because I am taking individual screen shots for later composition into a movie. Smooth motion results from the incremental change between shots.

- Is it about saving the scene (in a later phase) for each op the 24 steps during rotation?
No. I am able to save the screenshots and compose these into a movie.

Thanks also for the links. I have not yet experimented with the rotation:slerp() method. I will look at this as soon as possible.
I don't think that observer:goto(table) will help as I can not see any way of saving my screenshots while the goto executes.

To rephrase what I am trying to do;
I start with an observer positioned on the surface of the earth, looking at the horizon.
My script then raises the observer from the surface and turns the orientation towards the point on the surface from which it has left. I can successfully capture screen shots for this and compose these into a movie that runs smoothly.
My observer is then positioned a few thousand kilometers above the earth, looking at the point on the surface (ie, centered on the earth).
I now want to turn the observer to be centered on the moon, and be able to take a series of screen shots while this turn executes. The only way I can see of achieving this is to break the rotation into suitable segments then turn a segment, take a screenshot, turn a segment, take a screenshot etc until the rotation is complete.
This is what I am trying to achieve in the example code in my original post. In my larger script the screenshots are captured within the for loop in the rotate_obs function.
If you run the example code you will see that the observer turns towards the moon but does not end up centered. also, if you change the latitude and longitude values the rotations final orientation will change and the moon may not even be visible.

I think the problem must be either
a: the axis vector is wrong
or
b: I have a problem with reference frames or coordinate systems so the observer is not actually looking along the vector towards the moon.

Sorry for the long post but it is difficult to know how much detail to put in before making it too confusing.

Chris

Re: problem turning observer precise angle and axis

Posted: 15.04.2011, 16:20
by Marco Klunder
Voila :idea:

Code: Select all

uly_to_km = 9460730.4725808
--celestia:settime(2455505.77)
celestia:settimescale(0)
obs=celestia:getobserver()
sun=celestia:find("Sol")
earth = celestia:find("Sol/Earth")
moon= celestia:find("Sol/Earth/Moon")
obs:synchronous(earth)
alt=12000+earth:radius()
longitude=math.rad(147)
latitude=math.rad(-41)
obs:gotolonglat(earth,longitude,latitude,alt,1)
wait(2)
obspos=obs:getposition()
moonpos=moon:getposition()
earthpos=earth:getposition()

celestia:select(earth)
orient_earth = obspos:orientationto(earthpos, celestia:newvector(0, 1, 0))
-- Orientation from this position towards Moon
orient_moon = obspos:orientationto(moonpos, celestia:newvector(0, 1, 0))
-- Interpolate new observer orientation (middle)
for i=1,15 do
   orientation = orient_earth:slerp(orient_moon, i*0.04)
   obs:setorientation(orientation)
   celestia:flash(i)
   wait(0.5)
end
celestia:unmarkall()
celestia:setrenderflags{markers = true}
moon:mark("green", "uparrow", 20, 1, "Moon",false)
for i=16,25 do
   orientation = orient_earth:slerp(orient_moon, i*0.04)
   obs:setorientation(orientation)
   celestia:flash(i)
   wait(0.5)
end

wait(10)
celestia:unmarkall()
celestia:setrenderflags{markers = false}


Marco

Re: problem turning observer precise angle and axis

Posted: 16.04.2011, 13:59
by ChrisA
Many thanks Marco,
That will do just what I want.
Celx scripts are a wonderful and powerful tool. Unfortunately it is easy to get very confused while trying to learn the language. It is great to have this forum with helpful people like yourself to point people in the right direction when stuck.
Thanks again,
Chris