跳转至内容

Celestia/Celx 脚本/CELX Lua 方法/Celx 位置

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

Celx 脚本:位置

[编辑 | 编辑源代码]

一个“位置”对象包含空间中某一点的确切坐标。“位置”对象是相对于坐标系(即参考系,参见Celx 脚本:坐标系)的,可能需要将其转换为或从通用坐标转换为才能进一步使用。

在 CELX 脚本中,位置方法需要用获得的“位置”对象作为前缀,并用冒号隔开。

可以使用以下方法获取“位置”对象

备注

  1. Celestia 中的位置分量(X、Y、Z)以百万分之一光年存储。因此,如果您自己的位置以公里或英里定义,则必须转换这些位置。因此,您可以使用一个常量,它必须首先在您的脚本中初始化。
    • 从公里转换为百万分之一光年,使用常量 uly_to_km = 9460730.4725808。
    • 从英里转换为百万分之一光年,使用常量 uly_to_mls = 5912956.5453630。
  2. 接下来您可以将公里或英里转换为百万分之一光年,如下所示
    • 百万分之一光年 = number:km / uly_to_km
    • 百万分之一光年 = number:miles / uly_to_mls
  3. 内部“位置”对象每个分量使用 128 位,因此比 Lua 中直接可用(通常使用 64 位 IEEE754 双精度浮点数)的精度更高。但是,您可以在“位置”对象上执行的计算是有限的,因此您通常需要将“位置”对象转换为普通的 Lua 数字。
    为了避免精度问题,通常的做法是将“位置”对象转换为“向量”对象,相对于原点(例如太阳或太阳系质心)。您可以通过从对象或观察者位置减去原点位置来获得“向量”对象,如下所示
-- Get a vector giving the heliocentric position of the Earth
function earthpos(jd)
   local sun = celestia:find("Sol")
   local earth = celestia:find("Sol/Earth")
   return earth:getposition(jd) - sun:getposition(jd)
end

运算符

[编辑 | 编辑源代码]

“位置”对象可以相互加减。
也可以将“位置”对象与“向量”对象相加,或从“位置”对象中减去“向量”对象。

  • 位置 + 向量 → 位置
  • 位置 + 位置 → 位置
  • 位置 - 位置 → 向量
  • 位置 - 向量 → 位置

注意:减去两个“位置”对象会产生一个“向量”对象,而不是一个“位置”对象。

您可以直接访问和分配“位置”对象的 x、y 和 z 分量,例如

earth = celestia:find("Sol/Earth")
earthpos = earth:getposition() 
ep_x = earthpos.x
ep_y = earthpos.y
ep_z = earthpos.z
obs = celestia:getobserver()
obspos = obs:getposition()
obspos.x = 1
obspos.y = 0
obspos.x = 0
obs = celestia:setpostion(obspos)

注意:以这种方式访问分量会返回普通的 Lua 数字,这些数字的精度低于“位置”对象中存储的 128 位值。

本章列出了所有可用的位置方法,这些方法可用于“位置”对象。

addvector

[编辑 | 编辑源代码]

位置 position:addvector(vector:vec)

将向量添加到位置,并将结果作为“位置”对象返回。

参数

vec
要添加到位置的向量。必须是“向量”对象。

备注

  1. 您也可以使用 position = position + vector 代替此 position:addvector() 方法。两者结果相同。
  2. 与位置分量一样,Celestia 中的向量分量(X、Y、Z)也以百万分之一光年存储。
  3. CELX “位置”对象包含空间中某一点的确切坐标。位置是相对于坐标系的,可能需要将其转换为或从通用坐标转换为才能进一步使用。
  4. 位置方法可用于 CELX “位置”对象。“位置”对象也可用于其他方法,这些方法需要“位置”对象作为参数。

示例
转到地球在 1 天后将经过的路径旁边空间中的一个位置。从该位置观察地球,看看地球如何向你靠近并擦肩而过(时间加速了 3600 倍)。

-- Find and select Earth
earth = celestia:find("Sol/Earth")
celestia:select(earth)
obs = celestia:getobserver()
-- Set frame of reference to "universal".
obs:setframe(celestia:newframe("universal"))
-- Determine the actual position of Earth  
now = celestia:gettime()
posearth = earth:getposition(now)
-- Determine and goto new observer position, to just miss Earth within 1 day
newpos = earth:getposition(now+1)
vec = celestia:newvector(0, 0, 0.002)
newpos = newpos:addvector(vec)
obs:goto(newpos,1.0)
wait(0.0)
-- Look at Earth and see how it comes towards you
upvec = celestia:newvector(0,1,0)
obs:lookat(newpos, posearth, upvec)
celestia:settimescale(3600)
obs:track(earth)


返回 位置 方法索引。

向量 position:vectorto(position:target)

返回指向从当前位置到目标位置的“向量”对象。

参数

目标
向量应该指向的目标位置。必须是“位置”对象。

备注

  1. 您也可以使用 vector = position target - position source 代替此 position:vectorto() 方法。两者结果相同。
  2. 向量的精度(IEEE754 双精度浮点数)可能不足以精确地表达此距离。
  3. CELX “向量”对象是一个几何对象,在三维坐标系中具有长度和方向 [X、Y、Z]。
  4. 可以使用 CELX “向量”对象上的向量方法。“向量”对象也可用于其他方法,这些方法需要“向量”对象作为参数。

示例
获取一个向量,给出地球的日心位置

now = celestia:gettime()
sunpos = celestia:find("Sol"):getposition(now)
earthpos = celestia:find("Sol/Earth"):getposition(now)
heliovector = sunpos:vectorto(earthpos)


返回 位置 方法索引。

distanceto

[编辑 | 编辑源代码]

数字 position:distanceto(position:target)

返回从当前位置到目标位置的距离(以公里为单位),作为数字。

参数

目标
必须计算到目标位置。必须是“位置”对象。

示例
确定并显示观察者到海王星的实际距离。

now = celestia:gettime()
neptunepos = celestia:find("Sol/Neptune"):getposition(now)
obs = celestia:getobserver()
obspos = obs:getposition()
distance = obspos:distanceto(neptunepos)
celestia:print("The center of Neptune is " .. distance .. " km away", 10.0, -1, -1, 2, 4)
wait(10.0)


返回 位置 方法索引。

orientationto

[编辑 | 编辑源代码]

旋转 position:orientationto(position:target, vector:up)

返回一个“旋转”对象,可用于将观察者定向到从当前位置指向目标位置。

参数

目标
观察者应该关注的目标位置。必须是“位置”对象。
向上
向上向量,定义哪个轴应该指向向上。必须是“向量”对象。
不能与目标方向平行,否则旋转未定义。

备注

  1. CELX 的“旋转”对象在内部是一个四元数,这是在三维空间中描述旋转的一种数学方法(即可以将其转换为旋转矩阵)。旋转也可以用于描述物体的方向或观察者(即观察者看向哪里,以及“向上”的方向)。
  2. 可以在 CELX 的“旋转”对象上使用旋转方法。“旋转”对象也可以用在其他方法中,这些方法需要“旋转”对象作为参数。

示例
移动到火星旁边的一个位置,并将观察者朝向这颗行星的方向。

obs = celestia:getobserver()
-- Set frame of reference to "universal".
obs:setframe(celestia:newframe( "universal"))
-- Find the actual position of Mars.
mars = celestia:find("Sol/Mars")
marspos = mars:getposition()
-- Calculate new position just far away from Mars.
newpos = marspos + celestia:newvector(0, 0, 0.002)
obs:goto(newpos, 0.0)
wait(0.0)
-- view towards Mars and follow the planet
rotation = newpos:orientationto(marspos, celestia:newvector(0, 1, 0))
obs:setorientation(rotation)
obs:follow(mars)


返回 位置 方法索引。

number position:getx()

以数字形式返回位置的 X 坐标。

备注

  1. 精度以双精度浮点数形式返回,可能没有足够的精度来表示确切的位置。

示例
获取地球的实际位置,并在屏幕左下角显示该位置的 X、Y 和 Z 分量。

now = celestia:gettime()
earthpos = celestia:find("Sol/Earth"):getposition(now)
earthpos_x = earthpos:getx()
earthpos_y = earthpos:gety()
earthpos_z = earthpos:getz()
celestia:print("Universal position of Earth:\nX = " .. earthpos_x .. 
               "\nY = " .. earthpos_y .. "\nZ = " .. earthpos_z, 10.0, -1, -1, 2, 7)
wait(10.0)


返回 位置 方法索引。

number position:gety()

以数字形式返回位置的 Y 坐标。

备注

  1. 精度以双精度浮点数形式返回,可能没有足够的精度来表示确切的位置。

示例
获取地球的实际位置,并在屏幕左下角显示该位置的 X、Y 和 Z 分量。

now = celestia:gettime()
earthpos = celestia:find("Sol/Earth"):getposition(now)
earthpos_x = earthpos:getx()
earthpos_y = earthpos:gety()
earthpos_z = earthpos:getz()
celestia:print("Universal position of Earth:\nX = " .. earthpos_x .. 
               "\nY = " .. earthpos_y .. "\nZ = " .. earthpos_z, 10.0, -1, -1, 2, 7)
wait(10.0)


返回 位置 方法索引。

number position:getz()

以数字形式返回位置的 Z 坐标。

备注

  1. 精度以双精度浮点数形式返回,可能没有足够的精度来表示确切的位置。

示例
获取地球的实际位置,并在屏幕左下角显示该位置的 X、Y 和 Z 分量。

now = celestia:gettime()
earthpos = celestia:find("Sol/Earth"):getposition(now)
earthpos_x = earthpos:getx()
earthpos_y = earthpos:gety()
earthpos_z = earthpos:getz()
celestia:print("Universal position of Earth:\nX = " .. earthpos_x .. 
               "\nY = " .. earthpos_y .. "\nZ = " .. earthpos_z, 10.0, -1, -1, 2, 7)
wait(10.0)


返回 位置 方法索引。

华夏公益教科书