411 REFERENCE · Wikibooks
Celestia/Celx Scripting/CELX Lua Methods/Celx rotation
Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.
Celx Scripting: Rotation
rotation
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).
Within a CELX script, the rotation methods need to be prefixed with the obtained "rotation" object, separated with a colon.
The following methods can be used to obtain a "rotation" object:
Using the celestia:newrotation(axis-angle) method.
Using the celestia:newrotation() method.
Using the observer:getorientation() method.
Using the position:orientationto() method.
Using the frame:to(rotation) method.
Using the frame:from(rotation) method.
Using the rotation:slerp() method.
Using the phase:getorientation() method.
Methods
This chapter contains a list of all available rotation methods, which can be used on "rotation" objects.
imag
vector rotation:imag()
Return the X, Y and Z values of this rotation as a "vector" object.
Notes:
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:
obs = celestia:getobserver()
rot1 = obs:getorientation()
vector = rot1:imag()
Return to the rotation method index.
real
number rotation:real()
Return the W value of this rotation as a number.
Example:
obs = celestia:getobserver()
rot1 = obs:getorientation()
number = rot1:real()
Return to the rotation method index.
transform
vector rotation:transform(vector:vec)
Transform a "vector" object by applying the rotation to that vector and return the result in a new "vector" object.
vec The vector the rotation will be applied to. Must be a "vector" object.
Notes:
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:Goto a position at the actual dark side of Earth.
obs = celestia:getobserver()
-- Set frame of reference to "universal".
obs:setframe(celestia:newframe("universal"))
-- Find the Sun and Earth and get their actual positions
earth = celestia:find("Sol/Earth")
sun = celestia:find("Sol")
now = celestia:gettime()
earthpos = earth:getposition(now)
sunpos = sun:getposition(now)
-- Get vector from Earth to the Sun
vector1 = earthpos:vectorto(sunpos)
-- Transform that vector over a rotation of 180 degrees = math.pi
up_v = celestia:newvector(0,1,0)
opposite = celestia:newrotation(up_v, math.pi)
vector2 = opposite:transform(vector1)
-- Adjust the length of the opposite vector
vector2 = 0.0003 * vector2
-- Goto new position and center Earth.
newpos = earthpos + vector2
obs:goto(newpos, 0.0)
wait(0.0)
obs:center(earth, 0.0)
wait(0.0)
Return to the rotation method index.
setaxisangle
rotation:setaxisangle(vector:vec, number:angle)
Set axis and angle, as defined in the vector and angle for this rotation.
vec Vector describing the [X,Y,Z] axis for this rotation. Must be a "vector" object.
angle The angle in radians for this rotation. Must be a number.
Notes:
Angles in CELX are defined in radians instead of degrees. 180 degrees (half a circle) is the same as π radians = 3.14159265 radians = math.pi radians (LUA). You can convert degrees to radians and vice versa as follows:
radians = math.rad( number:degrees ) = ( number:degrees / 180 * math.pi) = ( number:degrees / 180 * 3.14159265).
degrees = math.deg( number:radians ) = ( number:radians * 180 / math.pi) = ( number:radians * 180 / 3.14159265).
This method is equivalent to celestia:newrotation(axis-angle) method. Only by using this method, the "rotation" object needs to be present first, instead of being created by the method. To obtain such a "rotation" object, the celestia:newrotation() method can be used instead, or you can use an already existing "rotation" object, previously defined within your script.
Example:Change the current observer view by 180 degrees (like a rear-view mirror).
obs = celestia:getobserver()
-- Create a rotation object from all zero numbers.
rot1 = celestia:newrotation(0, 0, 0, 0)
-- Define the axis for the rotation as a vector
up_vec = celestia:newvector(0, 1, 0)
rot1:setaxisangle(up_vec, math.pi)
obs:rotate(rot1)
wait(0.0)
Return to the rotation method index.
slerp
rotation:rot3 rotation:slerp(rotation:rot2, number:percent)
Return an interpolation of this rotation and another "rotation" object (rot2), using number to indicate how much of each rotation should be used. Return the result in a new "rotation" object (rot3).
rot2 Second rotation that will be used for the interpolation. Must be a "rotation" object.
percent The percent number used to interpolate between the two rotations. Must be a number between 0 and 1.
If percent is 0, this rotation is returned in rotation:rot3.
If percent is 1, the second rotation (rot2) is returned in rotation:rot3.
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 in the Earth-Moon system and set the observer orientation to the middle of the Earth-Moon positions.
obs = celestia:getobserver()
-- Set frame of reference to "universal".
obs:setframe(celestia:newframe( "universal"))
-- Find the actual position of the Earth.
earth = celestia:find("Sol/Earth")
earthpos = earth:getposition()
-- Find the actual position of the Moon.
moon = celestia:find("Sol/Earth/Moon")
moonpos = moon:getposition()
-- Calculate new position to goto
newpos = earthpos + 0.5 * (moonpos - earthpos)
newpos = newpos + celestia:newvector(0, 0, 0.075)
obs:goto(newpos, 0.0)
wait(0.0)
-- Orientation from this position towards Earth
orient_earth = newpos:orientationto(earthpos, celestia:newvector(0, 1, 0))
-- Orientation from this position towards Moon
orient_moon = newpos:orientationto(moonpos, celestia:newvector(0, 1, 0))
-- Interpolate new observer orientation (middle)
orientation = orient_earth:slerp(orient_moon, 0.5)
obs:setorientation(orientation)
Return to the rotation method index.