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)