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