Celestia/Celx 脚本/CELX Lua 方法/Celx 位置
一个“位置”对象包含空间中某一点的确切坐标。“位置”对象是相对于坐标系(即参考系,参见Celx 脚本:坐标系)的,可能需要将其转换为或从通用坐标转换为才能进一步使用。
在 CELX 脚本中,位置方法需要用获得的“位置”对象作为前缀,并用冒号隔开。
可以使用以下方法获取“位置”对象
- 使用celestia:newposition() 方法。
- 使用celestia:newposition(base64) 方法。
- 使用observer:getposition() 方法。
- 使用object:getposition() 方法。
- 使用position:addvector() 方法。
- 使用frame:to() 方法。
- 使用frame:from() 方法。
- 使用 1.6.0 phase:getposition() 方法。
备注
- Celestia 中的位置分量(X、Y、Z)以百万分之一光年存储。因此,如果您自己的位置以公里或英里定义,则必须转换这些位置。因此,您可以使用一个常量,它必须首先在您的脚本中初始化。
- 从公里转换为百万分之一光年,使用常量 uly_to_km = 9460730.4725808。
- 从英里转换为百万分之一光年,使用常量 uly_to_mls = 5912956.5453630。
- 接下来您可以将公里或英里转换为百万分之一光年,如下所示
- 百万分之一光年 = number:km / uly_to_km
- 百万分之一光年 = number:miles / uly_to_mls
- 内部“位置”对象每个分量使用 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 位值。
本章列出了所有可用的位置方法,这些方法可用于“位置”对象。
位置 position:addvector(vector:vec)
将向量添加到位置,并将结果作为“位置”对象返回。
参数
- vec
- 要添加到位置的向量。必须是“向量”对象。
备注
- 您也可以使用 position = position + vector 代替此 position:addvector() 方法。两者结果相同。
- 与位置分量一样,Celestia 中的向量分量(X、Y、Z)也以百万分之一光年存储。
- CELX “位置”对象包含空间中某一点的确切坐标。位置是相对于坐标系的,可能需要将其转换为或从通用坐标转换为才能进一步使用。
- 位置方法可用于 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)
返回指向从当前位置到目标位置的“向量”对象。
参数
- 目标
- 向量应该指向的目标位置。必须是“位置”对象。
备注
- 您也可以使用 vector = position target - position source 代替此 position:vectorto() 方法。两者结果相同。
- 向量的精度(IEEE754 双精度浮点数)可能不足以精确地表达此距离。
- CELX “向量”对象是一个几何对象,在三维坐标系中具有长度和方向 [X、Y、Z]。
- 可以使用 CELX “向量”对象上的向量方法。“向量”对象也可用于其他方法,这些方法需要“向量”对象作为参数。
示例
获取一个向量,给出地球的日心位置
now = celestia:gettime() sunpos = celestia:find("Sol"):getposition(now) earthpos = celestia:find("Sol/Earth"):getposition(now) heliovector = sunpos:vectorto(earthpos)
数字 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)
旋转 position:orientationto(position:target, vector:up)
返回一个“旋转”对象,可用于将观察者定向到从当前位置指向目标位置。
参数
- 目标
- 观察者应该关注的目标位置。必须是“位置”对象。
- 向上
- 向上向量,定义哪个轴应该指向向上。必须是“向量”对象。
不能与目标方向平行,否则旋转未定义。
备注
- CELX 的“旋转”对象在内部是一个四元数,这是在三维空间中描述旋转的一种数学方法(即可以将其转换为旋转矩阵)。旋转也可以用于描述物体的方向或观察者(即观察者看向哪里,以及“向上”的方向)。
- 可以在 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 坐标。
备注
- 精度以双精度浮点数形式返回,可能没有足够的精度来表示确切的位置。
示例
获取地球的实际位置,并在屏幕左下角显示该位置的 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 坐标。
备注
- 精度以双精度浮点数形式返回,可能没有足够的精度来表示确切的位置。
示例
获取地球的实际位置,并在屏幕左下角显示该位置的 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 坐标。
备注
- 精度以双精度浮点数形式返回,可能没有足够的精度来表示确切的位置。
示例
获取地球的实际位置,并在屏幕左下角显示该位置的 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)