连接点在空间中的位置

时间:2009-10-23 12:39:45

标签: algorithm math 3d

A-B-C-D是4分。我们定义r =长度(B-C),角度,ang1 =(A-B-C)和角度ang2 =(B-C-D),扭转角度tors1 =(A-B-C-D)。我真正需要做的是找到C和D的坐标,前提是我有r,ang1,ang2和tors1的新值。 问题在于,点A和B彼此刚性连接,并且点C和D也通过刚性连接器彼此连接,可以说。即距离(C-D)保持固定,距离A-B保持固定。 B点和C点之间没有这种严格的联系。

对于其他一组(r,ang1,ang2,tors1),我们有4个点的旧坐标,当这个定义的变量集变为某个任意值时,我们需要找到新的坐标。

对于任何有用的评论,我将不胜感激。 非常感谢。

我不允许发布图片,因为我是新用户:(

附加信息:迭代解决方案不会有用,因为我需要在模拟“很多次O(10 ^ 6)”中执行此操作。

5 个答案:

答案 0 :(得分:1)

我认为解决这个问题的最佳方法是考虑analytic geometry。 每个点A,B,C,D都有一些3D坐标(x,y,z),你之间有一些关系 它们(例如,距离B-C等于r表示

r = sqrt[ (x_b - x_c)^2 + (y_b - y_c)^2 + (z_b - z_c)^2 ]

一旦你定义了这样的关系,它仍然可以解决你需要确定的点坐标的未知值的最终方程组。

这是一种通用方法,如果您更好地描述问题(可能是图片?),由于您的问题具有某些特殊属性,因此可能很容易找到解决此类系统的一些有效方法。

答案 1 :(得分:1)

您尚未提及坐标系。即使(r,a1,a2,t)没有变化,如果可以将整个结构旋转到空间中,“坐标”也会改变。所以我会做一些假设:

将B置于原点,将C置于正X轴,将A置于XY平面中,使用y& gt0。如果您不知道距离AB,请从旧坐标计算它。同样CD。

A: (-AB cos(a1), AB sin(a1), 0)
B: (0, 0, 0)
C: (r, 0, 0)
D: (r + CD cos(a2), CD sin(a2) cos(t), CD sin(a2) sin(t))

(请注意角度中的符号约定。)

答案 2 :(得分:0)

您正在描述一组约束。

你需要做的是每次约束检查它们是否仍然满意,如果没有计算,则以最有效的方式再次纠正它。

例如,如果长度为b-c = r,如果b-c不再是r,则通过将b和c同时移动到彼此或从彼此移动来再次使其成为r,以便再次满足约束。

每个约束一个接一个地执行此操作。 然后重复几次,直到系统再次稳定(例如满足所有约束条件)。

就是这样

答案 3 :(得分:0)

您正在寻求非线性方程组的解决方案。对于数学倾向,我将写出约束方程:

假设您有A,B,C,D点的位置。我们定义向量AB = A-B等,此外,我们使用符号nAB来表示归一化向量AB / | AB |。有了这个符号,我们有:

AB.AB = fixed
CD.CD = fixed
CB.CB = r*r
nAB.nCB = cos(ang1)
nDC.nBC = cos(ang2)
Let E = D - DC.(nCB x nAB) // projection of D onto plane defined by ABC
nEC.nDC = cos(tors1)
nEC x nDC = sin(tors1) // not sure if your torsion angle is signed (if not, delete this)

其中点(。)表示点积,十字(x)表示叉积。 每个点由3个坐标定义,因此有12个未知数和6个约束方程,留下6个自由度,不受约束。这些是来自空间平移和旋转不变性的6个标准自由度。

假设您有旧点位置A',B',C'和D',并且您想找到一个新的解决方案,它与那些旧位置“最接近”(在某种意义上我定义),那么你是解决优化问题:

minimize: AA'.AA' + BB'.BB' + CC'.CC' + DD'.DD'
subject to the 4-5 constraints above.

这个优化问题没有很好的属性,因此你需要使用像Conjugate Gradient descent之类的东西来找到一个局部最优解,其中起始猜测是旧点位置。这是一个迭代解决方案,你说这是不可接受的,但除非你澄清你的问题,否则没有直接的解决方案。

如果这听起来不错,我可以详细说明执行数值优化的细节。

答案 4 :(得分:0)

这是一个与我已经给出的解决方案不同的解决方案。这里我假设A和B的位置不允许改变(即A和B的位置是常数),类似于Beta的解决方案。请注意,仍然存在无限数量的解,因为我们可以围绕由A-B定义的轴旋转结构,并且仍然满足所有约束。

让A的坐标为A [0],A [1]和A [2],类似于B.你想要C和D的显式方程式,正如你在Beta解决方案的响应中所提到的那样,所以这里他们是:

首先找到C的位置。如前所述,有无数种可能性,所以我会为你挑选一个好的。

Vector AB = A-B
Normalize(AB)

int best_i = 0;
for i = 1 to 2
    if AB[i] < AB[best_i]
       best_i = i
// best_i contains dimension in which AB is smallest

Vector N = Cross(AB, unit_vec[best_i]) // A good normal vector to AB
Normalize(N)

Vector T = Cross(N, AB) // AB, N, and T form an orthonormal frame
Normalize(T) // redundant, but just in case

C = B + r*AB*cos(ang1) + r*N*sin(ang1)

// Assume s is the known, fixed distance between C and D
// Update the frame
Vector BC = B-C, Normalize(BC)
N = Cross(BC, T), Normalize(N)

D = C + s*cos(tors1)*BC*cos(ang2) + s*cos(tors1)*N*sin(ang1) +/- s*sin(tors1)*T

最后的加或减取决于你如何定义标准正交框架。尝试一下,看看它是否是你想要的,否则就是另一个标志。上面的符号非常非正式,但它给出了如何从A,B和您的参数生成C和D的明确方法。它还选择一个好的C(取决于一个好的,非简并的N)。 unit_vec[i]指的是全零的向量,除了索引为i的1。像往常一样,我没有测试上面的伪代码:)