通过关于球体

时间:2015-10-30 17:51:06

标签: c++ geometry linear-algebra

我试图解决一个问题,我需要在P0的某个距离 P1周围投射一个关于已知半径的球体的弧,但是我的知识解决相当有限这种问题超出了标准的笛卡尔语境。

为了简化,如果我在飞机上这样做,我会简单地执行以下操作

float distance = 30;
Vector3 direction = (P1 - P0).Normalize();
Vector3 endPoint = P0 + (direction * distance);

我基本上试图看看是否有办法可以解决同样的问题,只能在球体上而不是在飞机上。这在概念上很困难,因为我需要考虑到P0和P1可以(并且将会)在球体上任意不同的高度。

我有一种感觉,我可能需要从笛卡尔转换为球形空间,但是在这里找到跳跃点已经证明非常困难。

思考?

2 个答案:

答案 0 :(得分:2)

设P0和P1为点,并考虑半径为r的球体。

首先,假设P0和P1位于球体上,并且我们想要行进距离d。首先请注意,我们需要P0≠P1,就像在线性代数情况下一样。 (否则,P0 = P1,因此通过P0和P1没有唯一的弧。)同样,我们需要P0≠-P1,否则通过P0和P1没有唯一的弧。

现在从P0到P1的弧位于所谓的球体的great circle。基本上,这是球体与某个平面通过O =(0,0,0)的交点。更确切地说,这是通过点O,P1和P2的唯一平面。

一些基本的线性代数将向您显示这是垂直于矢量P0×P1的平面,P0和P1的交叉积。注意,本产品中P0和P1的顺序为重要:通常,P0×P1≠P1×P0,如果我们取P1×P0,则运动方向将反转。 (即我们将从P1变为P0。)因此,P0到P1的“方向”由绕P0×P1的旋转给出。

现在考虑一般点P0,P1。正如melak47指出的那样,我们可以先将P0和P1投射到球体上,这样我们就可以在“方向”P0到P1上方进行旋转。为了将这些投影到球体上,我们还需要P0和P1都不为零,即不是原点。当P0和P1位于原点的同一条线上时,我们也遇到了一个问题,因为它们投射到球体上的相同点(或对映点),所以不要定义一个独特的弧:所以一般来说,我们需要检查P0和P1是linearly independent。现在注意P0位于半径为|| P0 ||的球体上,其中|| P0 ||是向量P0的范数。

请注意,上面介绍的半径r实际上还没有在任何地方使用过,所以我们可以设置r = || P0 ||。为了在弧P0到P1'上行进d的总距离,其中P1'被P1投影到半径为|| P0 ||的球上,角度变为d / || P0 ||,如上所述。好消息是P0×P1仍然是一个有效的旋转轴。

总而言之,您希望将P0绕P0×P1旋转d / || P0 ||弧度。在伪代码中,

float d;
Vector3 P0, P1;

float r = norm(P0);
float angle = d / r;
Vector3 axis = crossProduct(P0, P1);
Matrix3 rotationMatrix = RotationMatrix(angle, axis);
Vector3 endPoint = rotationMatrix * P0;

检查P0和P1是否线性独立与检查P0×P1非零相同,因此通常您可能需要在构造旋转之前检查axis != Vector3(0,0,0) 基质

如果您想要沿着弧P0'到P1的P0到P1方向行进,其中P0'被P0投影到半径为|| P1 ||的球上,我们首先需要替换r = norm(P0) r = norm(P1)(显然)。此外,P0'= || P1 || / || P0 || * P0,因此如果您愿意,我们还需要将rotationMatrix * P0替换为rotationMatrix * (r / norm(P0) * P0),或rotationMatrix * r * normalize(P0)

答案 1 :(得分:0)

IMO,你的问题没有一个答案。这似乎是一个2D问题,发生在由两个给定点和球体中心形成的平面中。

但是你需要对轨迹给出更多限制。它可以是一条直线,一个阿基米德螺旋,一个对数螺旋,一个样条......或者你喜欢的任何东西。

enter image description here