跳转到内容

Celestia/Celx 脚本/CELX Lua 方法/CEL 命令 orbit

来自维基教科书,自由的教学读物

orbit { duration <duration> rate <rate> axis <axisvector> }

在当前定义的坐标系下,围绕指定的 <axisvector>,以 <rate> 速度(以度/秒为单位)旋转当前选定的物体 <duration> 秒。你必须首先使用 select 命令选择一个物体,并且可以选择使用 setframe 命令来定义一个坐标系(如果当前没有定义的话)。

参数

duration <duration>
旋转物体的秒数。默认值为 1.0。
rate <rate>
旋转物体的速度,以度/秒为单位。默认值为 1.0。
正值和负值用于指示旋转方向(“+”号不是必需的)。
axis <axisvector>
定义要围绕哪个轴旋转 [x y z]。无默认值。
将 x、y 或 z 值设置为 1 表示 ,设置为 0 表示 。你也可以指定多个轴。


Celestia 版本 1.6.1 及更高版本的 CELX 等效项 - 1

基于 1.6.1 observer:orbit() 方法。

此等效项在 大约 <duration> 秒内,围绕参考物体旋转 正好 <duration> * <rate> 度。

  • 找到并选择名为 <string> 的要旋转的物体,并将其存储在“objectname”中。
objectname = celestia:find( <string> )
celestia:select(objectname)
  • 获取活动视图的观察者实例,并将其存储在“obs”中。
obs=celestia:getobserver()
  • 将“objectname”设置为“ecliptic”(跟随)参考系中的参考物体。
obs:follow(objectame)
  • "duration" = <duration> = 旋转持续时间(秒)。
duration = <duration>
  • <rate> 是旋转速度,以度/秒为单位,必须将其转换为弧度/秒,方法是将 <rate> 乘以 math.pi (= 3.14159265),然后除以 180,并将结果存储在“radiansrate”中。Lua 的 math.rad( <rate> ) 函数也可以用于此目的。
radiansrate = math.rad( <rate> )
  • 创建一个用于旋转轴的向量 <axisvector>。
axis_vector = celestia:newvector( <axisvector> )
  • 通过将 <duration> 乘以“radiansrate”来确定旋转角度(弧度)。
orbitangle = duration * radiansrate
  • 将旋转分成每秒 30 步,并确定每一步的旋转步长时间。
    因子 0.75 是一个估计值,可能取决于你的计算机速度。
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

总结

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

作为函数总结

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)


Celestia 版本 1.6.1 及更高版本的 CELX 等效项 - 2

基于 1.6.1 observer:orbit() 方法。

此等效项在 正好 <duration> 秒内,围绕参考物体旋转 大约 <duration> * <rate> 度。

  • 找到并选择名为 <string> 的要旋转的物体,并将其存储在“objectname”中。
objectname = celestia:find( <string> )
celestia:select(objectname)
  • 获取活动视图的观察者实例,并将其存储在“obs”中。
obs=celestia:getobserver()
  • 将“objectname”设置为“ecliptic”(跟随)参考系中的参考物体。
obs:follow(objectame)
  • "duration" = <duration> = 旋转持续时间(秒)。
duration = <duration>
  • <rate> 是旋转速度,以度/秒为单位,必须将其转换为弧度/秒,方法是将 <rate> 乘以 math.pi (= 3.14159265),然后除以 180,并将结果存储在“radiansrate”中。Lua 的 math.rad( <rate> ) 函数也可以用于此目的。
radiansrate = math.rad( <rate> )
  • 通过将 <duration> 乘以“radiansrate”来确定旋转角度(弧度)。
orbitangle = duration * radiansrate
  • 创建一个用于旋转轴的向量 <axisvector>。
axis_vector = celestia:newvector( <axisvector> )
  • 将旋转分成每秒 30 步,并确定每一步的旋转步长时间。
    因子 0.75 是一个估计值,可能取决于你的计算机速度。
orbitsteps = 30 * duration
orbitsteptime = 0.75*duration/orbitsteps
  • 创建一个新的旋转对象,围绕指定的轴旋转分段的旋转角度。
rot = celestia:newrotation(axis_vector, orbitangle/orbitsteps)
  • 获取脚本启动后经过的秒数,并将其存储在“t0”中。
t0 = celestia:getscripttime()
  • 实际执行旋转。
while celestia:getscripttime() <= t0 + duration do
   obs:orbit(rot)
   wait(orbitsteptime)
end

总结

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

作为函数总结

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 等效项 - 3

基于算术序列的方法。

注意:在此 CELX 等效项中无法定义 <axisvector>。

  • 找到并选择名为 <string> 的要旋转的物体,并将其存储在“objectname”中。
objectname = celestia:find( <string> )
celestia:select(objectname)
  • "duration" = <duration> = 旋转持续时间(秒)。
duration = <duration>
  • <rate> 是旋转速度,以度/秒为单位,必须将其转换为弧度/秒,方法是将 <rate> 乘以 math.pi (= 3.14159265),然后除以 180,并将结果存储在“radiansrate”中。Lua 的 math.rad( <rate> ) 函数也可以用于此目的。
radiansrate = math.rad( <rate> )
  • 获取活动视图的观察者实例,并将其存储在“obs”中。
obs=celestia:getobserver()

  • "v1" 是从观察者到“objectname”的向量,已归一化为长度 1。
    "up" 是相机向上方向(标准 Y 方向)。
    "v2" 是“v1”和“up”的正交向量,已归一化为长度 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()
  • 通过将 <duration> 乘以“radiansrate”来确定旋转角度(弧度)。
orbitangle = duration * radiansrate
  • 在包含“v1”且垂直于向上方向的平面上旋转 <duration> 秒。
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

总结

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

作为函数总结

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 )


示例
以下示例将土星旋转 12 秒。


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 }


使用 1.6.1 observer:orbit() 方法的 CELX

此等效项在 大约 12 秒内,围绕参考物体旋转 正好 12 * 30 = 360 度。

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


使用 1.6.1 observer:orbit() 方法在 函数 中的 CELX

此等效项在 大约 12 秒内,围绕参考物体旋转 正好 12 * 30 = 360 度。

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)


使用 1.6.1 observer:orbit() 方法的 CELX

此等效项在 正好 12 秒内,围绕参考物体旋转 大约 12 * 30 = 360 度。

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


使用 1.6.1 observer:orbit() 方法在 函数 中的 CELX

此等效项在 正好 12 秒内,围绕参考物体旋转 大约 12 * 30 = 360 度。

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

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

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)


返回 CEL 命令索引

华夏公益教科书