c - 我需要相对于三角形平移 3d 点,就好像三角形在其他地方一样

标签 c 3d rotational-matrices

我不久前在 Twitter 上发布了这个,但看到我的关注者似乎没有一个是数学/编程天才,我也想在这里碰碰运气。我来到这里是因为我找到了this其中可能包含我的部分解决方案。

我在下面描述了我的问题 pdf文档,其中包含我要实现的目标的图片。

为了提供更多细节,我将十二面体的五边形(12 个五边形)分成三角形(5 个/五边形,总共 60 个三角形),然后收集与这些三角形中的每一个相关的一组数据点。

想法是为每个单独的三角形生成地形网格。 为此,数据必须在 32K x 32K 正方形(idTech4 Megatexture)中以平面表示

我隐约听说过转换矩阵,如果设置得当,它可以通过它们传递所有数据点,让它们显示在正确的位置。

我看了这个源代码here但我不明白我应该如何获得点数和/或从那里获得点数,更不用说如何进行设置以便我可以依次呈现每个点并取回结果点。

我很快就确定了属于右后角的点。我所有的 3D 点最初都存储在纬度/经度对中。我以这种方式检索 3D vector :

coord getcoord(point* p) 
{
    coord c;
    c.x=cos(p->lat*pi/180.l) * cos(p->lon*pi/180.l);
    c.y=cos(p->lat*pi/180.l) * sin(p->lon*pi/180.l);
    c.z=sin(p->lat*pi/180.l);
    return c;
};

我的想法是,如果我能找到我的三角形的中心,并发现如何偏移我的角度,那么从我的球体中心到三角形中间的 vector 移动到 90N,那么我的点就已经在正确的平面,如果我沿着相同的角度旋转它们。如果我随后将它们全部转换为 3d 并从 y 中减去半径,它们也会位于正确的 y 位置。

然后我需要做的就是旋转、缩放和移动到最终位置。

三角形的“中心”有几种,我想我需要的是与三角形角点等距的那种(外心?)

但是可能会有更简单的方法来解决整个问题,所以当我继续自己的研究时,也许你们中的一些人可以帮助我指明正确的方向。

看起来好像一些样本数据是有序的,这里有一些 obj 文件格式的三角形:

v 0.000000 0.000000 3396.000000
v 2061.582356 0.000000 2698.646733
v 637.063983 1960.681333 2698.646733
f 1 2 3

还有一个:

v -938.631230 2888.810129 1518.737455
v 637.063983 1960.681333 2698.646733
v 1030.791271 3172.449325 637.064076
f 1 2 3

您会注意到每个点距离 0,0,0 的距离为 3396 我提到“在球体上”意味着远离球体中心的面是在转换为正方形时需要成为“顶部”的面。

理论上所有这些三角形实际上应该具有相同的大小,但由于生成它们的数学中的舍入误差,这可能不完全正确。

如果我没记错的话,我已经采取措施确保您在此处看到的第一个点始终是最长边框对面的那个点,因此它应该位于最左角(测试以上 2 个示例确认这个,但我正在测量只是为了确定) 从这一点引出的两条腿理论上也应该具有相同的长度,但舍入误差可能会略微抵消这一点。

如果我做对了,那么长边是 2 条短边的 1,113587 倍。假设它们是相同的,然后在 excel 中进行一些目标搜索,我可以推断出最后的分数,假设我只是在翻译这个三角形,应该如下所示:

v 16384.000000 0.000000 16384.000000
v -16384.000000 0.000000 9916.165306
v 9916.165306 0.000000 -16384.000000
f 1 2 3

所以我需要设置矩阵来执行此转换,最好使用 4x4 矩阵,如下所述。

最佳答案

我建议使用变换矩阵。 3d 变换矩阵是一个 4x4 数据结构,它描述了平移和旋转(可能还有比例)。一旦你有了一个矩阵,你就可以像这样转换一个点

 result.x = (tmp->pt.x * m->element[0][0]) + 
            (tmp->pt.y * m->element[1][0]) + 
            (tmp->pt.z * m->element[2][0]) + 
            m->element[3][0];

 result.y = (tmp->pt.x * m->element[0][1]) + 
            (tmp->pt.y * m->element[1][1]) + 
            (tmp->pt.z * m->element[2][1]) + 
            m->element[3][1];
 result.z = (tmp->pt.x * m->element[0][2]) + 
            (tmp->pt.y * m->element[1][2]) + 
            (tmp->pt.z * m->element[2][2]) + 
            m->element[3][2];
 int w = (tmp->pt.x * m->element[0][3]) + (tmp->pt.y * m->element[1][3])
      + (tmp->pt.z * m->element[2][3]) + m->element[3][3];
 if (w!=0 || w!=1)
 result.x/=w; result.y/=w; result.z/=w;

这将通过矩阵 m 转换 3D 点 pt。如果你现在有点矩阵数学你会看到我只是将我的原点作为 vector 乘以矩阵(如果它是一个偏斜矩阵则做一点归一化。)矩阵可以相乘形成复杂的变换所以它们非常有用。

有关制作矩阵的详细信息,建议阅读此链接。 http://en.wikipedia.org/wiki/Transformation_matrix

关于c - 我需要相对于三角形平移 3d 点,就好像三角形在其他地方一样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9087004/

相关文章:

javascript - 如何使用 three.js 'wrap' 球体上的平面?

python - 将旋转矩阵正确转换为 Mayavi/Vtk 的(俯仰、滚动、偏航)

c - 如何确定程序可以使用 unsigned long long 计算阶乘的最大值?

c - Strassen 奇数矩阵的优化静态填充

在 3D 网格中生成圆边和角的算法

c++ - 旋转几何以对齐方向 vector

python - 从随机生成的法向量进行坐标变换

c - 给定一个正整数,判断它是否等于四个连续整数之和

android - 映射共享库时出错

ios - Swift 3 - SceneKit 获取 3d 模型 X Y Z 旋转值