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)