Celestia/Celx Scripting/CELX Lua Methods/Celx position

Celx Scripting: Position

edit

position

edit

A "position" object contains the exact coordinates of a point in space. A "position" object is relative to a coordinate system (i.e. a frame of reference, see Celx Scripting: Frame) and may need to be converted to or from universal coordinates before further use.

Within a CELX script, the position methods need to be prefixed with the obtained "position" object, separated with a colon.

The following methods can be used to obtain a "position" object:

Notes:

  1. Position components (X,Y,Z) in Celestia are stored in millionths of a light year. So when you have your own positions defined in km or miles, you have to convert these positions. Therefore, you can use a constant, which must be initialized first within your script:
    • From km to millionths of a light year, use a constant uly_to_km = 9460730.4725808.
    • From miles to millionths of a light year, use a constant uly_to_mls = 5912956.5453630.
  2. Next you can convert km or miles to millionths of a light year as follows:
    • millionths_of_a_light_year = number:km / uly_to_km
    • millionths_of_a_light_year = number:miles / uly_to_mls
  3. Internally "position" objects use 128 bit per component and therefore have higher precision than available directly in Lua (which typically uses 64-bit IEEE754 double precision floating point numbers). The calculations that you can perform however on a "position" object are limited, so you'll often want to convert "position" objects to normal Lua numbers.
    In order to avoid precision problems, the usual practice is to convert a "position" object to a "vector" object, relative to the origin (such as the Sun or Solar System Barycenter). You can do this by subtracting the origin's position from the object- or observer position to get a "vector" object like this:
-- Get a vector giving the heliocentric position of the Earth
function earthpos(jd)
   local sun = celestia:find("Sol")
   local earth = celestia:find("Sol/Earth")
   return earth:getposition(jd) - sun:getposition(jd)
end

Operators

edit

"Position" objects can be added and subtracted from each other.
It is also possible to add a "position" object with a "vector" object, or subtract a "vector" object from a "position" object.

  • position + vector → position
  • position + position → position
  • position - position → vector
  • position - vector → position

Note:Subtracting two "position" objects produces a "vector" object and NOT a "position" object.

Members

edit

You can access and assign the x, y, and z components of a "position" object directly, e.g.

earth = celestia:find("Sol/Earth")
earthpos = earth:getposition() 
ep_x = earthpos.x
ep_y = earthpos.y
ep_z = earthpos.z
obs = celestia:getobserver()
obspos = obs:getposition()
obspos.x = 1
obspos.y = 0
obspos.x = 0
obs = celestia:setpostion(obspos)

Note: Accessing components this way returns normal Lua numbers, which have less precision than the 128-bit values stored in a "position" object.

Methods

edit

This chapter contains a list of all available position methods, which can be used on "position" objects.

addvector

edit

position position:addvector(vector:vec)

Add a vector to the position and return the result as a "position" object.

Arguments:

vec
The vector to be added to the position. Must be a "vector" object.

Notes:

  1. You can also use position = position + vector instead of this position:addvector() method. Both have the same result.
  2. Like position components, the vector components (X,Y,Z) in Celestia are also stored in millionths of a light year.
  3. A CELX "position" object contains the exact coordinates of a point in space. A position is relative to a coordinate system and may need to be converted to or from universal coordinates before further use.
  4. The position methods can be used on a CELX "position" object. "Position" objects can also be used in other methods, requiring a "position" object as an argument.

Example:
Goto a position in space just beside the path where Earth will be over 1 day. Look from that position at Earth and see how Earth comes towards you and just misses you (time is sped up 3600x).

-- Find and select Earth
earth = celestia:find("Sol/Earth")
celestia:select(earth)
obs = celestia:getobserver()
-- Set frame of reference to "universal".
obs:setframe(celestia:newframe("universal"))
-- Determine the actual position of Earth  
now = celestia:gettime()
posearth = earth:getposition(now)
-- Determine and goto new observer position, to just miss Earth within 1 day
newpos = earth:getposition(now+1)
vec = celestia:newvector(0, 0, 0.002)
newpos = newpos:addvector(vec)
obs:goto(newpos,1.0)
wait(0.0)
-- Look at Earth and see how it comes towards you
upvec = celestia:newvector(0,1,0)
obs:lookat(newpos, posearth, upvec)
celestia:settimescale(3600)
obs:track(earth)


Return to the position method index.

vectorto

edit

vector position:vectorto(position:target)

Return the "vector" object, pointing from this position to the target position.

Arguments:

target
The target position the vector should be pointing to. Must be a "position" object.

Notes:

  1. You can also use vector = position target - position source instead of this position:vectorto() method. Both have the same result.
  2. The precision of a vector (IEEE754 double precision floating point) may be insufficient to express this distance exactly.
  3. A CELX "vector" object is a geometric object that has both a length and direction [X, Y, Z] in a 3 dimensional coordinate system.
  4. The vector methods can be used on a CELX "vector" object. "Vector" objects can also be used in other methods, requiring a "vector" object as an argument.

Example:
Get a vector, giving the heliocentric position of the Earth

now = celestia:gettime()
sunpos = celestia:find("Sol"):getposition(now)
earthpos = celestia:find("Sol/Earth"):getposition(now)
heliovector = sunpos:vectorto(earthpos)


Return to the position method index.

distanceto

edit

number position:distanceto(position:target)

Return the distance in kilometers from this position to the target position, as a number.

Arguments:

target
The target position the distance must be calculated to. Must be a "position" object.

Example:
Determine and display the actual distance from the obserber to Neptune.

now = celestia:gettime()
neptunepos = celestia:find("Sol/Neptune"):getposition(now)
obs = celestia:getobserver()
obspos = obs:getposition()
distance = obspos:distanceto(neptunepos)
celestia:print("The center of Neptune is " .. distance .. " km away", 10.0, -1, -1, 2, 4)
wait(10.0)


Return to the position method index.

orientationto

edit

rotation position:orientationto(position:target, vector:up)

Return a "rotation" object which can be used to orient a viewer to point from this position toward the target position.

Arguments:

target
The target position at which the viewer should focus on. Must be a "position" object.
up
The up vector, defining which axis should be pointing up. Must be a "vector" object.
Must not be parallel to the target direction, otherwise the rotation is undefined.

Notes:

  1. A CELX "rotation" object is internally a Quaternion, which is one possibility to mathematically describe a rotation in 3 dimensions (i.e. it can be converted to a rotation matrix). A rotation can also be used to describe the orientation of objects or the observer (i.e. where the observer is looking to, and where "up" is).
  2. The rotation methods can be used on a CELX "rotation" object. "Rotation" objects can also be used in other methods, requiring a "rotation" object as an argument.

Example:
Goto a position just beside Mars and orient the observer towards the planet.

obs = celestia:getobserver()
-- Set frame of reference to "universal".
obs:setframe(celestia:newframe( "universal"))
-- Find the actual position of Mars.
mars = celestia:find("Sol/Mars")
marspos = mars:getposition()
-- Calculate new position just far away from Mars.
newpos = marspos + celestia:newvector(0, 0, 0.002)
obs:goto(newpos, 0.0)
wait(0.0)
-- view towards Mars and follow the planet
rotation = newpos:orientationto(marspos, celestia:newvector(0, 1, 0))
obs:setorientation(rotation)
obs:follow(mars)


Return to the position method index.

getx

edit

number position:getx()

Return the X coordinate of the position as a number.

Notes:

  1. The precision is returned as a double-precision floating point value and may not have sufficient precision to express the exact position.

Example:
Get the actual position of Earth and display the X-, Y- and Z-components of that position in the lower left corner of the screen.

now = celestia:gettime()
earthpos = celestia:find("Sol/Earth"):getposition(now)
earthpos_x = earthpos:getx()
earthpos_y = earthpos:gety()
earthpos_z = earthpos:getz()
celestia:print("Universal position of Earth:\nX = " .. earthpos_x .. 
               "\nY = " .. earthpos_y .. "\nZ = " .. earthpos_z, 10.0, -1, -1, 2, 7)
wait(10.0)


Return to the position method index.

gety

edit

number position:gety()

Return the Y coordinate of the position as a number.

Notes:

  1. The precision is returned as a double-precision floating point value and may not have sufficient precision to express the exact position.

Example:
Get the actual position of Earth and display the X-, Y- and Z-components of that position in the lower left corner of the screen.

now = celestia:gettime()
earthpos = celestia:find("Sol/Earth"):getposition(now)
earthpos_x = earthpos:getx()
earthpos_y = earthpos:gety()
earthpos_z = earthpos:getz()
celestia:print("Universal position of Earth:\nX = " .. earthpos_x .. 
               "\nY = " .. earthpos_y .. "\nZ = " .. earthpos_z, 10.0, -1, -1, 2, 7)
wait(10.0)


Return to the position method index.

getz

edit

number position:getz()

Return the Z coordinate of the position as a number.

Notes:

  1. The precision is returned as a double-precision floating point value and may not have sufficient precision to express the exact position.

Example:
Get the actual position of Earth and display the X-, Y- and Z-components of that position in the lower left corner of the screen.

now = celestia:gettime()
earthpos = celestia:find("Sol/Earth"):getposition(now)
earthpos_x = earthpos:getx()
earthpos_y = earthpos:gety()
earthpos_z = earthpos:getz()
celestia:print("Universal position of Earth:\nX = " .. earthpos_x .. 
               "\nY = " .. earthpos_y .. "\nZ = " .. earthpos_z, 10.0, -1, -1, 2, 7)
wait(10.0)


Return to the position method index.