# Celestia/Celx Scripting/CELX Lua Methods/Celx position

# Celx Scripting: Position[edit | edit source]

## position[edit | edit source]

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:

- Using the celestia:newposition() method.
- Using the celestia:newposition(base64) method.
- Using the observer:getposition() method.
- Using the object:getposition() method.
- Using the position:addvector() method.
- Using the frame:to() method.
- Using the frame:from() method.
- Using the 1.6.0 phase:getposition() method.

**Notes:**

- 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.

- 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

- millionths_of_a_light_year =
- 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 | edit source]

"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 | edit source]

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 | edit source]

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

### addvector[edit | edit source]

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:**

- You can also use
**position = position + vector**instead of this**position:addvector()**method. Both have the same result. - Like position components, the vector components (X,Y,Z) in Celestia are also stored in millionths of a light year.
- 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.
- 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 | edit source]

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:**

- You can also use
**vector = position target - position source**instead of this**position:vectorto()**method. Both have the same result. - The precision of a vector (IEEE754 double precision floating point) may be insufficient to express this distance exactly.
- A CELX "vector" object is a geometric object that has both a length and direction [X, Y, Z] in a 3 dimensional coordinate system.
- 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 | edit source]

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 | edit source]

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:**

- 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).
- 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 | edit source]

number **position:getx()**

Return the X coordinate of the position as a number.

**Notes:**

- 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 | edit source]

number **position:gety()**

Return the Y coordinate of the position as a number.

**Notes:**

- 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 | edit source]

number **position:getz()**

Return the Z coordinate of the position as a number.

**Notes:**

- 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)