Celestia/Celx Scripting/CELX Lua Methods/CEL command orbit

orbit
orbit { duration  rate  axis  } 

Orbit the currently selected object during  seconds at  speed (in units of degrees per second), using the currently defined Coordinate System, around the specified . You must first use the select command to select an object, and optionally use the setframe command to define a Coordinate System, if one is not currently defined.

CELX equivalent-1 for Celestia version and later:

Based on the observer:orbit method.

This equivalent orbits the reference object during about  seconds over exactly  *  degrees.


 * Find and select the object with name  that must be orbited and store in "objectname".

objectname = celestia:find(  ) celestia:select(objectname)


 * Get observer instance of the active view and store in "obs".

obs=celestia:getobserver


 * Make "objectname" the reference object in the "ecliptic" (follow) frame of reference.

obs:follow(objectame)


 * "duration" =  = the duration of the orbit in seconds.

duration = 


 *  is the orbit velocity in degrees per second, which must be transformed in radians per second by multiplying the  with math.pi (= 3.14159265) and divide by 180 and stored in "radiansrate". The Lua math.rad(  ) function can also be used for this.

radiansrate = math.rad( <rate> )


 * Create a vector <axisvector> for the axis to orbit around.

axis_vector = celestia:newvector( <axisvector> )


 * Determine the orbit angle in radians by multiplying <duration> with "radiansrate".

orbitangle = duration * radiansrate


 * Split up the orbit in 30 steps per second and determine the orbit steptime for each single step. The factor 0.75 is an estimate and may depend on the speed of your computer.

orbitsteps = 30 * duration orbitsteptime = 0.75*duration/orbitsteps


 * Create new rotation object of split up orbit angle around the specified axis.

rot = celestia:newrotation(axis_vector, orbitangle/orbitsteps)


 * Actually execute the orbit.

for i = 1, orbitsteps do   obs:orbit(rot) wait(orbitsteptime) end

Summarized:

objectname = celestia:find( <string> ) celestia:select(objectname) obs=celestia:getobserver obs:follow(objectame) duration = <duration> radiansrate = math.rad( <rate> ) axis_vector = celestia:newvector( <axisvector> ) orbitangle = duration * radiansrate orbitsteps = 30 * duration orbitsteptime = 0.75*duration/orbitsteps rot = celestia:newrotation(axis_vector, orbitangle/orbitsteps) for i = 1, orbitsteps do   obs:orbit(rot) wait(orbitsteptime) end

Summarized as a function:

function orbit_object_angle(period, orbitrate, axis) local orbitangle = period * orbitrate local orbitsteps = 30 * period local orbitsteptime = 0.75*period/orbitsteps local rot = celestia:newrotation(axis, orbitangle/orbitsteps) local obs = celestia:getobserver for i = 1, orbitsteps do      obs:orbit(rot) wait(orbitsteptime) end end objectname = celestia:find( <string> ) celestia:select(objectname) obs = celestia:getobserver obs:follow(objectame) radiansrate = math.rad( <rate> ) axis_vector = celestia:newvector( <axisvector> ) orbit_object_angle( <duration>, radiansrate, axis_vector)

CELX equivalent-2 for Celestia version and later:

Based on the observer:orbit method.

This equivalent orbits the reference object during exacly <duration> seconds over about <duration> * <rate> degrees.


 * Find and select the object with name <string> that must be orbited and store in "objectname".

objectname = celestia:find( <string> ) celestia:select(objectname)


 * Get observer instance of the active view and store in "obs".

obs=celestia:getobserver


 * Make "objectname" the reference object in the "ecliptic" (follow) frame of reference.

obs:follow(objectame)


 * "duration" = <duration> = the duration of the orbit in seconds.

duration = <duration>


 * <rate> is the orbit velocity in degrees per second, which must be transformed in radians per second by multiplying the <rate> with math.pi (= 3.14159265) and divide by 180 and stored in "radiansrate". The Lua math.rad( <rate> ) function can also be used for this.

radiansrate = math.rad( <rate> )


 * Determine the orbit angle in radians by multiplying <duration> with "radiansrate".

orbitangle = duration * radiansrate


 * Create a vector <axisvector> for the axis to orbit around.

axis_vector = celestia:newvector( <axisvector> )


 * Split up the orbit in 30 steps per second and determine the orbit steptime for each single step. The factor 0.75 is an estimate and may depend on the speed of your computer.

orbitsteps = 30 * duration orbitsteptime = 0.75*duration/orbitsteps


 * Create new rotation object of split up orbit angle around the specified axis.

rot = celestia:newrotation(axis_vector, orbitangle/orbitsteps)


 * Get the elapsed time in seconds since the script has been started and store in "t0".

t0 = celestia:getscripttime


 * Actually execute the orbit.

while celestia:getscripttime <= t0 + duration do   obs:orbit(rot) wait(orbitsteptime) end

Summarized:

objectname = celestia:find( <string> ) celestia:select(objectname) obs=celestia:getobserver obs:follow(objectame) duration = <duration> radiansrate = math.rad( <rate> ) orbitangle = duration * radiansrate axis_vector = celestia:newvector( <axisvector> ) orbitsteps = 30 * duration orbitsteptime = 0.75*duration/orbitsteps rot = celestia:newrotation(axis_vector, orbitangle/orbitsteps) t0 = celestia:getscripttime while celestia:getscripttime <= t0 + duration do   obs:orbit(rot) wait(orbitsteptime) end

Summarized as a function:

function orbit_object_time(period, orbitrate, axis) local orbitangle = period * orbitrate local orbitsteps = 30 * period local orbitsteptime = 0.75*period/orbitsteps local rot = celestia:newrotation(axis, orbitangle/orbitsteps) local obs = celestia:getobserver local t0 = celestia:getscripttime while celestia:getscripttime <= t0 + period do      obs:orbit(rot) wait(orbitsteptime) end end objectname = celestia:find( <string> ) celestia:select(objectname) obs = celestia:getobserver obs:follow(objectame) radiansrate = math.rad( <rate> ) axis_vector = celestia:newvector( <axisvector> ) orbit_object_time( <duration>, radiansrate, axis_vector)

CELX equivalent-3:

Based on an arithmetic sequence of methods.

Note: NO <axisvector> can be defined in this CELX equivalent.


 * Find and select the object with name <string> that must be orbited and store in "objectname".

objectname = celestia:find( <string> ) celestia:select(objectname)


 * "duration" = <duration> = the duration of the orbit in seconds.

duration = <duration>


 * <rate> is the orbit velocity in degrees per second, which must be transformed in radians per second by multiplying the <rate> with math.pi (= 3.14159265) and divide by 180 and stored in "radiansrate". The Lua math.rad( <rate> ) function can also be used for this.

radiansrate = math.rad( <rate> )


 * Get observer instance of the active view and store in "obs".

obs=celestia:getobserver
 * "v1" is the vector from the viewer to "objectname", normalized to length 1. "up" is the camera up direction (standard Y-direction). "v2" is normal to both "v1" and "up", normalized to length 1.

now = celestia:gettime v1 = obs:getposition - objectname:getposition(now) distance = v1:length v1 = v1:normalize up = obs:getorientation:transform(celestia:newvector(0, 1, 0)) v2 = v1 ^ up v2 = v2:normalize


 * Determine the orbit angle in radians by multiplying <duration> with "radiansrate".

orbitangle = duration * radiansrate


 * Orbit in the plane containing "v1" and normal to the up direction in <duration> seconds

start = celestia:getscripttime t = (celestia:getscripttime - start) / duration while t < 1 do   t = (celestia:getscripttime - start) / duration theta = orbitangle * t   v = math.cos(theta) * v1 + math.sin(theta) * v2    obs:setposition(objectname:getposition + v * distance) obs:lookat(objectname:getposition, up) wait(0) end

Summarized:

objectname = celestia:find( <string> ) celestia:select(objectname) duration = <duration> radiansrate = math.rad( <rate> ) obs=celestia:getobserver now = celestia:gettime v1 = obs:getposition - objectname:getposition(now) distance = v1:length v1 = v1:normalize up = obs:getorientation:transform(celestia:newvector(0, 1, 0)) v2 = v1 ^ up v2 = v2:normalize orbitangle = duration * radiansrate start = celestia:getscripttime t = (celestia:getscripttime - start) / duration while t < 1 do   t = (celestia:getscripttime - start) / duration theta = orbitangle * t   v = math.cos(theta) * v1 + math.sin(theta) * v2    obs:setposition(objectname:getposition + v * distance) obs:lookat(objectname:getposition, up) wait(0) end

Summarized as a function:

function orbit_object(period, orbitrate) -- Period is the duration of the orbit in seconds -- Orbitrate is the orbit velocity in radians per second local obs = celestia:getobserver local obsframe = obs:getframe local center = obsframe:getrefobject -- If there's no followed object, use the current selection if not center then center = celestia:getselection end if not center then return end -- v1 is the vector from the viewer to the center -- up is the camera up direction -- v2 is normal to both v1 and up   local now = celestia:gettime local v1 = obs:getposition - center:getposition(now) local distance = v1:length v1 = v1:normalize local up = obs:getorientation:transform(celestia:newvector(0, 1, 0)) local v2 = v1 ^ up   v2 = v2:normalize -- Determine orbit angle in radians local orbitangle = period * orbitrate -- Orbit in the plane containing v1 and normal to the up direction local start = celestia:getscripttime local t = (celestia:getscripttime - start) / period while t < 1 do      t = (celestia:getscripttime - start) / period local theta = orbitangle * t      local v = math.cos(theta) * v1 + math.sin(theta) * v2       obs:setposition(center:getposition + v * distance) obs:lookat(center:getposition, up) wait(0) end end objectname = celestia:find( <string> ) celestia:select(objectname) radiansrate = math.rad( <rate> ) orbit_object( <duration>, radiansrate )

Example: The following example orbits Saturn for 12 seconds.

CEL:

select { object "Sol/Saturn" } center { } goto  { time 3 distance 8 up [ 0 1 0 ] upframe "equatorial" } wait  { duration 3 } orbit { axis [ 0 1 0 ] rate 30 duration 12 }

CELX with the observer:orbit method:

This equivalent orbits the reference object during about 12 seconds over exactly 12 * 30 = 360 degrees.

objectname = celestia:find("Sol/Saturn" ) celestia:select(objectname) obs = celestia:getobserver obs:center(objectname, 1.0) wait(1.0) frame = celestia:newframe("equatorial", objectname) obs:setframe(frame) radius = objectname:radius distance = ( 8 + 1 ) * radius obs:gotodistance(objectname, distance, 3.0) wait(3.0) duration = 12.0 radiansrate = math.rad( 30.0 ) axis_vector = celestia:newvector( 0, 1, 0 ) orbitangle = duration * radiansrate orbitsteps = 30 * duration orbitsteptime = 0.75*duration/orbitsteps rot = celestia:newrotation(axis_vector, orbitangle/orbitsteps) for i = 1, orbitsteps do   obs:orbit(rot) wait(orbitsteptime) end

CELX with the observer:orbit method in a function:

This equivalent orbits the reference object during about 12 seconds over exactly 12 * 30 = 360 degrees.

function orbit_object_angle(period, orbitrate, axis) local orbitangle = period * orbitrate local orbitsteps = 30 * period local orbitsteptime = 0.75*period/orbitsteps local rot = celestia:newrotation(axis, orbitangle/orbitsteps) local obs = celestia:getobserver for i = 1, orbitsteps do      obs:orbit(rot) wait(orbitsteptime) end end objectname = celestia:find("Sol/Saturn" ) celestia:select(objectname) obs = celestia:getobserver obs:center(objectname, 1.0) wait(1.0) frame = celestia:newframe("equatorial", objectname) obs:setframe(frame) radius = objectname:radius distance = ( 8 + 1 ) * radius obs:gotodistance(objectname, distance, 3.0) wait(3.0) radiansrate = math.rad( 30.0 ) axis_vector = celestia:newvector( 0, 1, 0 ) orbit_object_angle(12.0, radiansrate, axis_vector)

CELX with the observer:orbit method:

This equivalent orbits the reference object during exacly 12 seconds over about 12 * 30 = 360 degrees.

objectname = celestia:find("Sol/Saturn" ) celestia:select(objectname) obs = celestia:getobserver obs:center(objectname, 1.0) wait(1.0) frame = celestia:newframe("equatorial", objectname) obs:setframe(frame) radius = objectname:radius distance = ( 8 + 1 ) * radius obs:gotodistance(objectname, distance, 3.0) wait(3.0) duration = 12.0 radiansrate = math.rad( 30.0 ) axis_vector = celestia:newvector( 0, 1, 0 ) orbitangle = duration * radiansrate orbitsteps = 30 * duration orbitsteptime = 0.75*duration/orbitsteps rot = celestia:newrotation(axis_vector, orbitangle/orbitsteps) t0 = celestia:getscripttime while celestia:getscripttime <= t0 + duration do   obs:orbit(rot) wait(orbitsteptime) end

CELX with the observer:orbit method in a function:

This equivalent orbits the reference object during exacly 12 seconds over about 12 * 30 = 360 degrees.

function orbit_object_time(period, orbitrate, axis) local orbitangle = period * orbitrate local orbitsteps = 30 * period local orbitsteptime = 0.75*period/orbitsteps local rot = celestia:newrotation(axis, orbitangle/orbitsteps) local obs = celestia:getobserver local t0 = celestia:getscripttime while celestia:getscripttime <= t0 + period do      obs:orbit(rot) wait(orbitsteptime) end end objectname = celestia:find("Sol/Saturn" ) celestia:select(objectname) obs = celestia:getobserver obs:center(objectname, 1.0) wait(1.0) frame = celestia:newframe("equatorial", objectname) obs:setframe(frame) radius = objectname:radius distance = ( 8 + 1 ) * radius obs:gotodistance(objectname, distance, 3.0) wait(3.0) radiansrate = math.rad( 30.0 ) axis_vector = celestia:newvector( 0, 1, 0 ) orbit_object_time(12.0, radiansrate, axis_vector)

CELX with an arithmetic sequence of methods:

objectname = celestia:find("Sol/Saturn" ) celestia:select(objectname) obs = celestia:getobserver obs:center(objectname, 1.0) wait(1.0) frame = celestia:newframe("equatorial", objectname) obs:setframe(frame) radius = objectname:radius distance = ( 8 + 1 ) * radius obs:gotodistance(objectname, distance, 3.0) wait(3.0) duration = 12.0 radiansrate = math.rad(30.0) obs=celestia:getobserver now = celestia:gettime v1 = obs:getposition - objectname:getposition(now) distance = v1:length v1 = v1:normalize up = obs:getorientation:transform(celestia:newvector(0, 1, 0)) v2 = v1 ^ up v2 = v2:normalize orbitangle = duration * radiansrate start = celestia:getscripttime t = (celestia:getscripttime - start) / duration while t < 1 do   t = (celestia:getscripttime - start) / duration theta = orbitangle * t   v = math.cos(theta) * v1 + math.sin(theta) * v2    obs:setposition(objectname:getposition + v * distance) obs:lookat(objectname:getposition, up) wait(0) end

CELX with an arithmetic sequence of methods in a function:

function orbit_object(period, orbitrate) -- Period is the duration of the orbit in seconds -- Orbitrate is the orbit velocity in radians per second local obs = celestia:getobserver local obsframe = obs:getframe local center = obsframe:getrefobject -- If there's no followed object, use the current selection if not center then center = celestia:getselection end if not center then return end -- v1 is the vector from the viewer to the center -- up is the camera up direction -- v2 is normal to both v1 and up   -- Orbit in the plane containing v1 and normal to the up direction local now = celestia:gettime local v1 = obs:getposition - center:getposition(now) local distance = v1:length v1 = v1:normalize local up = obs:getorientation:transform(celestia:newvector(0, 1, 0)) local v2 = v1 ^ up   v2 = v2:normalize local orbitangle = period * orbitrate local start = celestia:getscripttime local t = (celestia:getscripttime - start) / period while t < 1 do      t = (celestia:getscripttime - start) / period local theta = orbitangle * t      local v = math.cos(theta) * v1 + math.sin(theta) * v2       obs:setposition(center:getposition + v * distance) obs:lookat(center:getposition, up) wait(0) end end objectname = celestia:find("Sol/Saturn" ) celestia:select(objectname) obs = celestia:getobserver obs:center(objectname, 1.0) wait(1.0) frame = celestia:newframe("equatorial", objectname) obs:setframe(frame) radius = objectname:radius distance = ( 8 + 1 ) * radius obs:gotodistance(objectname, distance, 3.0) wait(3.0) radiansrate = math.rad(30.0) orbit_object(12.0, radiansrate)

Back to CEL command index