跳轉到內容

Celestia/Celx 指令碼/CELX Lua 方法/CEL 命令 gotoloc

來自華夏公益教科書,開放的書籍,開放的世界

gotoloc { time <duration> position <vector> xrot <xrot> yrot <yrot> zrot <zrot> }

-- 或者 --

gotoloc { time <duration> x <xbase64> y <ybase64> z <zbase64> ow <ownumber> ox <oxnumber> oy <oynumber> oz <oznumber> }

將相機移動到當前選定的物體,花費<duration>秒,移動到指定的位置(或來自 Cell://URL 的 Base64 值 x、y 和 z),使用透過 xrot、yrot 和 zrot(或 ow、ox、oy 和 oz)指定的方位。

引數

time <duration>
將物體居中所需的時間(秒)。預設值為 1.0 秒。
position <vector>
在當前座標系中定義一個點,以公里為單位。預設值為 [0 1 0]。
對於除通用座標系之外的所有座標系,position 為 [ 0 0 0 ] 是物體的中心。
您指定的公里值必須包含物體的半徑。
  • 第一個值 <xnumber> 表示相機位置,以公里為單位,沿著 X 軸。
  • 第二個值 <ynumber> 表示相機位置,以公里為單位,沿著 Y 軸。
  • 第三個值 <znumber> 表示相機位置,以公里為單位,沿著 Z 軸。
xrot <xrot>
相機方位,以度為單位的“尤拉角”或“角度-軸”表示。預設值為 0。
可以把它想象成航空中的俯仰。
yrot <yrot>
相機方位,以度為單位的“尤拉角”或“角度-軸”表示。預設值為 0。
可以把它想象成航空中的偏航。
zrot <zrot>
相機方位,以度為單位的“尤拉角”或“角度-軸”表示。預設值為 0。
可以把它想象成航空中的滾轉。

-- 或者 --

引數

time <duration>
將物體居中所需的時間(秒)。沒有預設值。
x <xbase64>
此值表示 CelURL 中儲存的 X 位置。沒有預設值。
該值可以從 CelURL 值之後獲取:?x=
y <ybase64>
此值表示 CelURL 中儲存的 Y 位置。沒有預設值。
該值可以從 CelURL 值之後獲取:&y=
z <zbase64>
此值表示 CelURL 中儲存的 Z 位置。沒有預設值。
該值可以從 CelURL 值之後獲取:&z=
ow <ownumber>
此值表示 CelURL 中儲存的 OW 方位。沒有預設值。
該值可以從 CelURL 值之後獲取:&ow=
ox <oxnumber>
此值表示 CelURL 中儲存的 OW 方位。沒有預設值。
該值可以從 CelURL 值之後獲取:&ox=
oy <oynumber>
此值表示 CelURL 中儲存的 OW 方位。沒有預設值。
該值可以從 CelURL 值之後獲取:&oy=
oz <oznumber>
此值表示 CelURL 中儲存的 OW 方位。沒有預設值。
該值可以從 CelURL 值之後獲取:&oz=


CELX 等效-1

基於引數列表-1observer:setorientation()observer:gotolocation()方法。

注意:這種方法組合的缺點是這些方法的順序執行,新的觀察者方位是立即設定的,而不是在 goto 期間平滑地設定。

  • 從 <xnumber>、<ynumber> 和 <znumber> 建立新的位置物件,並存儲在 "pos" 中。
    位置物件的元件單位是光年的百萬分之一,因此您必須將 km 轉換為光年的百萬分之一,使用 "uly_to_km" 常量。
uly_to_km = 9460730.4725808
pos = celestia:newposition( <xnumber>/uly_to_km, <ynumber>/uly_to_km, <znumber>/uly_to_km )
  • 指定並建立此旋轉的軸 [<xrot> , <yrot> , <zrot> ],並將其儲存在 "vec" 中。
    <xrot> 、<yrot> 和 <zrot> 是相機方位的“尤拉角”或“角度-軸”表示,以度為單位。
    可以把它想象成航空中的俯仰、偏航和滾轉。
vec = celestia:newvector( <xrot> , <yrot> , <zrot> )
  • 建立繞指定軸的新旋轉(即四元數),並將其儲存在 "rot" 中。
    "angle" = math.pi / 180 (= 3.14159265 / 180),用於從度數獲得弧度。
angle = math.pi/180
rot = celestia:newrotation(vec, angle)
  • 獲取活動檢視例項的觀察者例項,並根據建立的新旋轉 "rot" 旋轉觀察者。
obs = celestia:getobserver()
obs:setorientation(rot)
  • 在 <duration> 秒內移動到目標位置 "pos"。
obs:gotolocation(pos, <duration> )
  • 等待 <duration> 秒。
wait( <duration> )

總結

uly_to_km = 9460730.4725808
pos = celestia:newposition( <xnumber>/uly_to_km, <ynumber>/uly_to_km, <znumber>/uly_to_km )
vec = celestia:newvector( <xrot> , <yrot> , <zrot> )
angle = math.pi/180
rot = celestia:newrotation(vec, angle)
obs = celestia:getobserver()
obs:setorientation(rot)
obs:gotolocation(pos, <duration> )
wait( <duration> )


CELX 等效-2

基於引數列表-2observer:setorientation()observer:gotolocation()方法。

注意:這種方法組合的缺點是這些方法的順序執行,新的觀察者方位是立即設定的,而不是在 goto 期間平滑地設定。

  • 從 URL 樣式的 Base64 編碼值建立新的位置物件,並將其儲存在 "pos" 中。
    <xbase64>: 新向量的 X 分量,作為從 cel 樣式 URL ?x= 獲取的字串值。
    <ybase64>: 新向量的 Y 分量,作為從 cel 樣式 URL &y= 獲取的字串值。
    <zbase64>: 新向量的 Z 分量,作為從 cel 樣式 URL &z= 獲取的字串值。
pos = celestia:newposition( <xbase64>, <ybase64>, <zbase64> )
  • 從四個標量值(CEL://URL 中使用的值)建立新的旋轉(即四元數),並將其儲存在 "rot" 中。
    <ownumber>: 新旋轉的 OW 分量,作為從 cel 樣式 URL &ow= 獲取的數字值。
    <oxnumber>: 新旋轉的 OX 分量,作為從 cel 樣式 URL &ox= 獲取的數字值。
    <oynumber>: 新旋轉的 OY 分量,作為從 cel 樣式 URL &oy= 獲取的數字值。
    <oznumber>: 新旋轉的 OZ 分量,作為從 cel 樣式 URL &oz= 獲取的數字值。
rot = celestia:newrotation( <ownumber>, <oxnumber>, <oynumber>, <oznumber> )
  • 獲取活動檢視的觀察者例項,並根據建立的新旋轉 "rot" 旋轉觀察者。
obs = celestia:getobserver()
obs:setorientation(rot)
  • 在 <duration> 秒內移動到目標位置 “pos”。
obs:gotolocation(pos, <duration> )
  • 等待 <duration> 秒。
wait( <duration> )

總結

pos = celestia:newposition( <xbase64>, <ybase64>, <zbase64> )
rot = celestia:newrotation( <ownumber>, <oxnumber>, <oynumber>, <oznumber> )
obs = celestia:getobserver()
obs:setorientation(rot)
obs:gotolocation(pos, <duration> )
wait( <duration> )


CELX 等效-3

基於observer:goto(table)方法。

使用此方法,可以執行許多不同型別的 goto。此方法的優勢是可以對觀察者方位進行程式設計和插值,因此可以在 goto 期間改變觀察者的方位。

此方法使用位置物件進行 goto,並使用旋轉物件設定觀察者方位。位置和旋轉都可以從引數列表-1引數列表-2引數中提取。goto 的引數必須在表中給出

    • parameters.duration: 持續時間(數字)
    • parameters.from: 源位置
    • parameters.to: 目標位置
    • parameters.initialOrientation: 源方位
    • parameters.finalOrientation: 目標方位
    • parameters.startInterpolation
    • parameters.endInterpolation
    • parameters.accelTime


  • 獲取活動檢視的觀察者例項,並將其儲存在 "obs" 中。
obs = celestia:getobserver()
  • 定義並初始化引數表如下
    • 確定 goto 應該花費的時間(秒)。
    • 獲取觀察者的當前位置。
    • 建立新的位置物件。關於最初使用的 CEL 引數列表,有兩種可能性
      • 從 <xnumber>、<ynumber> 和 <znumber> 建立,並將其儲存在 "parameters.to" 中。位置物件的元件單位是光年的百萬分之一,因此您必須將 km 轉換為光年的百萬分之一,使用 “uly_to_km”。
        注意:給定的位置預計是相對於通用參考系,而非基於表的 goto 使用相對於當前參考系的位置。因此,根據使用的參考系,您必須先將位置轉換為通用!
      • 從 URL 樣式的 Base64 編碼值建立,並將其儲存在 "parameters.to" 中
        <xbase64>: 新向量的 X 分量,作為從 cel 樣式 URL ?x= 獲取的字串值。
        <ybase64>: 新向量的 Y 分量,作為從 cel 樣式 URL &y= 獲取的字串值。
        <zbase64>: 新向量的 Z 分量,作為從 cel 樣式 URL &z= 獲取的字串值。
    • 獲取觀察者的當前方位。
    • 建立新的旋轉物件。關於最初使用的 CEL 引數列表,有兩種可能性
      • 指定並建立觀察者旋轉的軸 [<xrot> , <yrot> , <zrot> ],並將其儲存在 "vec" 中。<xrot> 、<yrot> 和 <zrot> 是觀察者方位的“尤拉角”或“角度-軸”表示,以度為單位。可以把它想象成航空中的俯仰、偏航和滾轉。然後建立繞指定軸的新旋轉(即四元數),並使用 "angle" = math.pi/180 (= 3.14159265 / 180),從度數獲得弧度。將此新的旋轉儲存在 "parameters.finalOrientation" 中。
      • 從四個標量值(CEL://URL 中使用的值)建立,並將其儲存在 "parameters.finalOrientation" 中。
        <ownumber>: 新旋轉的 OW 分量,作為從 cel 樣式 URL &ow= 獲取的數字值。
        <oxnumber>: 新旋轉的 OX 分量,作為從 cel 樣式 URL &ox= 獲取的數字值。
        <oynumber>: 新旋轉的 OY 分量,作為從 cel 樣式 URL &oy= 獲取的數字值。
        <oznumber>: 新旋轉的 OZ 分量,作為從 cel 樣式 URL &oz= 獲取的數字值。
    • 在 goto 的 20% 時間之後開始調整觀察者方位。
    • 在 goto 的 80% 時間之後結束調整觀察者方位。
    • 花費 10% 的時間進行加速和減速
parameters={}
parameters.duration = <duration>
parameters.from = obs:getposition()
uly_to_km = 9460730.4725808
parameters.to = celestia:newposition( <xnumber>/uly_to_km, <ynumber>/uly_to_km, <znumber>/uly_to_km )
parameters.initialOrientation = obs:getorientation()
vec = celestia:newvector( <xrot> , <yrot> , <zrot> )
angle = math.pi/180
parameters.finalOrientation = celestia:newrotation(vec, angle)
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters. accelTime = 0.1

-- 或者 --

parameters={}
parameters.duration = <duration>
parameters.from = obs:getposition()
parameters.to = celestia:newposition( <xbase64>, <ybase64>, <zbase64> )
parameters.initialOrientation = obs:getorientation()
parameters.finalOrientation = celestia:newrotation( <ownumber>, <oxnumber>, <oynumber>, <oznumber> )
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters. accelTime = 0.1
  • 在 <duration> 秒內以目標方位移動到目標位置。
obs:goto(parameters)
  • 等待 <duration> 秒。
wait(parameters.duration)


總結

-- Use the following block of code for target positions
-- relative to the universal frame-of-reference:
obs = celestia:getobserver()
parameters={}
parameters.duration = <duration>
parameters.from = obs:getposition()
uly_to_km = 9460730.4725808
parameters.to = celestia:newposition( <xnumber>/uly_to_km, <ynumber>/uly_to_km, <znumber>/uly_to_km )
parameters.initialOrientation = obs:getorientation()
vec = celestia:newvector( <xrot> , <yrot> , <zrot> )
angle = math.pi/180
parameters.finalOrientation = celestia:newrotation(vec, angle)
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters.accelTime = 0.1
obs:goto(parameters)
wait(parameters.duration)

-- 或者 --

–- Use the following block of code for target positions
-- relative to the ecliptic (follow) frame of reference,
-- with "objectname" as reference object.
obs = celestia:getobserver()
objectname = celestia:find( <string> )
obs:follow(objectname)
parameters={}
parameters.duration = <duration>
parameters.from = obs:getposition()
uly_to_km = 9460730.4725808
vector = celestia:newvector( <xnumber>/uly_to_km, <ynumber>/uly_to_km, <znumber>/ uly_to_km )
objectpos = objectname:getposition()
parameters.to = objectpos + vector
parameters.initialOrientation = obs:getorientation()
vec = celestia:newvector( <xrot> , <yrot> , <zrot> )
angle = math.pi/180
parameters.finalOrientation = celestia:newrotation(vec, angle)
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters.accelTime = 0.1
obs:goto(parameters)
wait(parameters.duration)

-- 或者 --

obs = celestia:getobserver()
parameters={}
parameters.duration = <duration>
parameters.from = obs:getposition()
parameters.to = celestia:newposition( <xbase64>, <ybase64>, <zbase64> )
parameters.initialOrientation = obs:getorientation()
parameters.finalOrientation = celestia:newrotation( <ownumber>, <oxnumber>,  <oynumber>, <oznumber> )
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters.accelTime = 0.1
obs:goto(parameters)
wait(parameters.duration)

示例
以下示例演示了兩種gotoloc方法。它移動到地球,設定一個位置,這樣您就可以看到美國上空的燈光,在顯示器的左上角看到太陽,在右上角看到月亮。

注意: 以“#” (CEL) 和 “--” (CELX) 開頭的程式碼行是用於進一步解釋的註釋行

注意: 此示例中的 CelURL 值與 Celestia 版本 1.6.0 相容。

CEL

# Pause time and set the date and time to 2003 Aug 23 04:37:24 UTC
  timerate  { rate 0 }
  time      { jd 2452874.692638889 }
# Activate markers, clear all existing markers and
# place a blue square marker around the Moon...
  renderflags { set "markers" }
  unmarkall { }
  mark      { object "Sol/Earth/Moon" size 20.0 color [0 0 1] symbol "square" }
# Set the Field Of View value to 47.0 degrees...
  set       { name "FOV" value 47.0 }
# Select, follow and center Earth (so the coordinate system
# of the frame of reference is set to ecliptic).
  select    { object "Sol/Earth" }
  follow    { }
  center    { }
  wait      { duration 1 }
# Goto location: X = +7000km, Y = +9000km, Z = +11000km.
# Pitch Up +13 degrees (down = -), Yaw Left -32 degrees (right = +),
# Roll 0 degrees (left = - , right = +)
  gotoloc   { time 5 position [7000 9000 11000] xrot 13 yrot -32 zrot 0 }
  wait      { duration 5 }
  print     { text "Blue square is the Moon ---" duration 4 row -24 column 32 }
  wait      { duration 6 }
  print { text "First result done." duration 3 row -3 column 2 }
  wait { duration 3 }
  cancel { }
# Goto location using URL-style Base64-encoded values.
  gotoloc { time 5 x "AAAAbtdBM3XLDA" y "aG/b0Q34Pw" z "AABiyVOKuxUI"
            ow 0.703773 ox 0.068516 oy -0.703786 oz 0.068514 }
  wait { duration 5 }
  print { text "Second result done." duration 4  row -3 column 2 }
  wait { duration 4 }

CELX-1 使用 observer:gotolocation() 方法

-- Pause time and set the date and time to 2003 Aug 23 04:37:24 UTC.
-- First convert UTC to TDB date/time:
--    UTC is used in the Celestia's Set Time dialog and it's also
--    the time displayed in the upper right of the screen.
--    TDB = Barycentric Dynamical Time.
--    When using scripts for Celestia, the time scale is TDB !!!
celestia:settimescale(0)
dt=celestia:utctotdb(2003, 08, 23, 04, 37, 24)
celestia:settime(dt)
-- Activate markers, clear all existing markers and
-- place a blue square marker around the Moon...
celestia:setrenderflags{markers=true}
celestia:unmarkall()
moon = celestia:find("Sol/Earth/Moon")
moon:mark("blue", "square", 20.0)
-- Set the Field Of View value to 47.0 degrees.
-- In CELX, angles are stored in radians, instead of degrees, so you have to convert
-- degrees to radians by multiplying degrees with math.pi (= 3.14159265) and divide
-- by 180. The LUA "math.rad()" function can also be used for this.
obs = celestia:getobserver()
obs:setfov(47*math.pi/180)
-- Select, follow and center Earth (so the coordinate system
-- of the frame of reference is set to ecliptic).
earth = celestia:find("Sol/Earth")
celestia:select(earth)
obs:follow(earth)
obs:center(earth, 1.0)
wait(1.0)
-- Goto location: X = +7000km, Y = +9000km, Z = +11000km.
-- Pitch Up +13 degrees (down = -),
-- Yaw Left -32 degrees (right = +),
-- Roll 0 degrees (left = - , right = +)
obs = celestia:getobserver()
-- In CELX, angles are stored in radians, instead of degrees, so you have to convert
-- degrees to radians by multiplying degrees with math.pi (= 3.14159265) and divide
-- by 180. The LUA "math.rad()" function can also be used for this.
vec = celestia:newvector(13, -32, 0)
angle = math.pi/180
-- Set the observer orientation:
rot = celestia:newrotation(vec, angle)
obs:setorientation(rot)
-- In CELX, positions are stored in millionths of a light year,
-- so you have to convert km to millionths of a light year, using "uly_to_km".
uly_to_km = 9460730.4725808
pos = celestia:newposition(7000/uly_to_km, 9000/uly_to_km, 11000/uly_to_km)
-- Goto target position.
obs:gotolocation(pos, 5.0 )
wait(5.0)
celestia:print("Blue square is the Moon ---" , 4.0, -1, -1, 32, 24)
wait(6.0)
celestia:print("First result done.", 3.0, -1, -1, 2, 3)
wait(3.0)
-- Cancel GOTO and TRACK commands, and reset the Coordinate System to universal.
obs:cancelgoto()
obs:track(nil)
obs:setframe(celestia:newframe("universal"))
-- Goto target position, using URL-style Base64-encoded values.
obs = celestia:getobserver()
rot = celestia:newrotation(0.703773, 0.068516, -0.703786, 0.068514)
obs:setorientation(rot)
pos = celestia:newposition("AAAAbtdBM3XLDA", "aG/b0Q34Pw", "AABiyVOKuxUI")
obs:gotolocation(pos, 5.0 )
wait(5.0)
celestia:print("Second result done.", 4.0, -1, -1, 2, 3)
wait(4.0)

CELX-2 使用 observer:goto(table) 方法

-- Pause time and set the date and time to 2003 Aug 23 04:37:24 UTC.
-- First convert UTC to TDB date/time:
--    UTC is used in the Celestia's Set Time dialog and it's also
--    the time displayed in the upper right of the screen.
--    TDB = Barycentric Dynamical Time.
--    When using scripts for Celestia, the time scale is TDB !!!
celestia:settimescale(0)
dt=celestia:utctotdb(2003, 08, 23, 04, 37, 24)
celestia:settime(dt)
-- Activate markers, clear all existing markers and
-- place a blue square marker around the Moon...
celestia:setrenderflags{markers=true}
celestia:unmarkall()
moon = celestia:find("Sol/Earth/Moon")
moon:mark("blue", "square", 20.0)
-- Set the Field Of View value to 47.0 degrees.
-- In CELX, angles are stored in radians, instead of degrees, so you have to convert
-- degrees to radians by multiplying degrees with math.pi (= 3.14159265) and divide
-- by 180. The LUA "math.rad()" function can also be used for this.
obs = celestia:getobserver()
obs:setfov(47*math.pi/180)
-- Select, follow and center Earth (so the coordinate system
-- of the frame of reference is set to ecliptic).
earth = celestia:find("Sol/Earth")
celestia:select(earth)
obs:follow(earth)
obs:center(earth, 1.0)
wait(1.0)
-- Goto location: X = +7000km, Y = +9000km, Z = +11000km, relative to Earth !!!!
-- Pitch Up +13 degrees (down = -),
-- Yaw Left -32 degrees (right = +),
-- Roll 0 degrees (left = - , right = +)
obs = celestia:getobserver()
parameters={}
parameters.duration = 5.0
parameters.from = obs:getposition()
-- In CELX, positions are stored in millionths of a light year,
-- so you have to convert km to millionths of a light year, using "uly_to_km".
uly_to_km = 9460730.4725808
vec = celestia:newvector(7000/uly_to_km, 9000/uly_to_km, 11000/uly_to_km)
earthpos = earth:getposition()
parameters.to = earthpos + vec
parameters.initialOrientation = obs:getorientation()
-- In CELX, angles are stored in radians, instead of degrees, so you have to convert
-- degrees to radians by multiplying degrees with math.pi (= 3.14159265) and divide
-- by 180. The LUA "math.rad()" function can also be used for this.
vec = celestia:newvector(13, -32, 0)
angle = math.pi/180
-- Set the observer orientation:
parameters.finalOrientation = celestia:newrotation(vec, angle)
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters.accelTime = 0.1
-- Goto target position.
obs:goto(parameters)
wait(parameters.duration)
celestia:print("Blue square is the Moon ---" , 4.0, -1, -1, 32, 24)
wait(6.0)
celestia:print("First result done.", 3.0, -1, -1, 2, 3)
wait(3.0)
-- Cancel GOTO and TRACK commands, and reset the Coordinate System to universal.
obs:cancelgoto()
obs:track(nil)
obs:setframe(celestia:newframe("universal"))
-- Goto target position, using URL-style Base64-encoded values.
parameters={}
parameters.duration = 5.0
parameters.from = obs:getposition()
parameters.to = celestia:newposition("AAAAbtdBM3XLDA", "aG/b0Q34Pw", "AABiyVOKuxUI")
parameters.initialOrientation = obs:getorientation()
parameters.finalOrientation = celestia:newrotation(0.703773, 0.068516, -0.703786, 0.068514)
parameters.startInterpolation = 0.2
parameters.endInterpolation = 0.8
parameters.accelTime = 0.1
-- Goto target position.
obs:goto(parameters)
wait(parameters.duration)
celestia:print("Second result done.", 4.0, -1, -1, 2, 3)
wait(4.0)


返回 CEL 命令索引

華夏公益教科書