叠加和对齐 3D 三角形时出现问题

2023-11-23

我正在尝试叠加两个 3D 三角形来解决分子建模问题。这看起来很简单。我将每个三角形的第一个点平移到原点 0,0,0。然后我计算了必须绕 z 轴旋转的角度才能将第二个点放在 x 轴上。使用 Rz(theta) 的 x、y、z 公式,这将是以下角度:y=0, y=xsin(theta)+ycos(theta)=0,并重新排列,tan(theta)=-y/x角度将是arctan(-y/x)。但是,将这个角度值代入上面的原始方程不会给出零,除非在以下情况x=y,且正切为一。看起来像简单的代数 - 为什么这不起作用? 谢谢你的帮助。


正如其他评论所暗示的那样,您很可能对投影和测角学感到困惑。还有一种更安全的方法,无需使用矢量数学(线性代数)进行测角。

  1. 创建变换矩阵m0表示与第一个三角形对齐的平面t0

    通过对齐我的意思是三角形的边之一应该位于平面基向量之一中。这很简单,您只需将一个基向量设置为相关边缘,将原点设置为其点之一,然后利用叉积来获取剩余的向量。

    所以如果我们的三角形有点p0,p1,p2我们的基向量是x,y,z有起源o then:

    x = p1-p0;      x /= |x|;
    y = p2-p0; 
    z = cross(x,y); z /= |z|;
    y = cross(z,x); y /= |y|;
    o = p0
    

    所以只需将它们输入变换矩阵(请参阅答案底部的链接)

  2. 创建变换矩阵m1表示与第二个三角形对齐的平面t1

    它等同于#1

  3. 计算最终变换矩阵m转换t1 to t0

    这很简单:

    m = Inverse(m1)*m0
    

现在任意一点t1可以对齐到t0简单地通过乘法m矩阵按点。不要忘记使用齐次坐标,这样point(x,y,z,1)

这里小C++/OpenGL例子:

//---------------------------------------------------------------------------
double t0[3][3]=    // 1st triangle
    {
    -0.5,-0.5,-1.2,
    +0.5,-0.5,-0.8,
     0.0,+0.5,-1.0,
    };
double t1[3][3]=    // 2nd triangle
    {
    +0.5,-0.6,-2.1,
    +1.5,-0.5,-2.3,
    +1.2,+0.3,-2.2,
    };
double arot=0.0; // animation angle
//---------------------------------------------------------------------------
void gl_draw()      // main rendering code
    {
    int i;
    double m0[16],m1[16],m[16],x[3],y[3],z[3],t2[3][3];

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDisable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslated(0.0,0.0,-10.0);
    glRotatef(arot,0.0,1.0,0.0); 

    // render original triangles
    glBegin(GL_TRIANGLES);
    glColor3f(1.0,0.0,0.0); for (i=0;i<3;i++) glVertex3dv(t0[i]);
    glColor3f(0.0,0.0,1.0); for (i=0;i<3;i++) glVertex3dv(t1[i]);
    glEnd();

    // x,y,z = t0 plane basis vectors
    vector_sub(x,t0[1],t0[0]);  // x is fisrt edge
    vector_one(x,x);            // normalized
    vector_sub(y,t0[2],t0[0]);  // y is last edge
    vector_mul(z,x,y);          // z = cross(x,y) ... perpendicular vector to x,y
    vector_one(z,z);
    vector_mul(y,z,x);          // y = cross(z,x) ... perpendicular vector to z,x
    vector_one(y,y);
    // m0 = transform matrix representing t0 plane
    m0[ 3]=0.0; for (i=0;i<3;i++) m0[ 0+i]=x[i];
    m0[ 7]=0.0; for (i=0;i<3;i++) m0[ 4+i]=y[i];
    m0[11]=0.0; for (i=0;i<3;i++) m0[ 8+i]=z[i];
    m0[15]=1.0; for (i=0;i<3;i++) m0[12+i]=t0[0][i];

    // x,y,z = t1 plane basis vectors
    vector_sub(x,t1[1],t1[0]);  // x is fisrt edge
    vector_one(x,x);            // normalized
    vector_sub(y,t1[2],t1[0]);  // y is last edge
    vector_mul(z,x,y);          // z = cross(x,y) ... perpendicular vector to x,y
    vector_one(z,z);
    vector_mul(y,z,x);          // y = cross(z,x) ... perpendicular vector to z,x
    vector_one(y,y);
    // m1 = transform matrix representing t1 plane
    m1[ 3]=0.0; for (i=0;i<3;i++) m1[ 0+i]=x[i];
    m1[ 7]=0.0; for (i=0;i<3;i++) m1[ 4+i]=y[i];
    m1[11]=0.0; for (i=0;i<3;i++) m1[ 8+i]=z[i];
    m1[15]=1.0; for (i=0;i<3;i++) m1[12+i]=t1[0][i];

    // m = transform t1 -> t0 = Inverse(m1)*m0
    matrix_inv(m,m1);
    matrix_mul(m,m,m0);

    // t2 = transformed t1
    for (i=0;i<3;i++) matrix_mul_vector(t2[i],m,t1[i]);

    // render transformed triangle
    glLineWidth(2.0);
    glBegin(GL_LINE_LOOP);
    glColor3f(0.0,1.0,0.0); for (i=0;i<3;i++) glVertex3dv(t2[i]);
    glLineWidth(1.0);
    glEnd();

    glFlush();
    SwapBuffers(hdc);
    }
//---------------------------------------------------------------------------

我使用了自己的矩阵和向量数学,希望评论足够,如果没有看到的话:

  • 理解 4x4 齐次变换矩阵

有关矩阵的信息,您也可以找到那里使用的数学的来源和方程。这里是我的测试用例的预览:

preview

红色在哪里t0蓝色三角形是t1三角形和绿色是m*t1变换后的三角形。正如您所看到的,根本不需要测角/欧拉角。我旋转这些东西arot只是为了目视检查绿色三角形是否真的与蓝色对齐,以证明我没有犯一个愚蠢的错误。

现在还不清楚您到底想要如何对齐,因此,例如,如果您想要最大覆盖范围或尝试所有 3 种组合并记住最佳组合,或者对齐到两个三角形的最近或最大边缘等...

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

叠加和对齐 3D 三角形时出现问题 的相关文章

  • 如何在 Three.js 中从三角面获取多边形?

    我在网上查了一下是否有人遇到同样的问题 我正在使用 Three js 我有一个 3DObject 其中可能包含孔 面是三角形的 假设我想从上面看到它 我的目标是获得一个代表顶面周长的多边形 这对我来说意味着不再有三角面 而只有 1 个多边形
  • 基于正方形瓷砖直角三角形象限的坐标系中的边界框

    我正在为游戏创建一个基于图块的 2D 地形系统 然而 我还使用游戏中的坐标 需要能够将边界框映射到 图块坐标 中 并点击边界框接触的每个图块 不用担心 有一个 kd 树和所有工作 美好的 使用定点 真实世界 坐标 我可以将每个图块计为 2
  • 使用圆点填充圆,使用圆边缘的偏置

    这就是我想要实现的目标 到目前为止 我对我拥有的代码感到满意 这是从 Wolfram 和另一个数学来源借来的 但我不知道如何整合一些偏差计算 或者只是一种分配随机但有组织的内容的方法 有人能指出我正确的方向吗 这是我的代码 它将使用 P5
  • 在iOS开发中,使用Core Graphics和/或Quartz 2D,如何绘制一个充满渐变的圆,使其看起来像一个球体?

    到目前为止 我已经研究过使用 CGContextDrawLinearGradient 和 CGContextDrawRadialGradient 但是 对于前者 我无法弄清楚如何使渐变看起来像球体 对于后者 我无法弄清楚如何使渐变成球体形状
  • 在二维空间中从 A 点前往 B 点?

    我正在开发一个项目 需要我计算从可变点 A 到可变点 B 的 0 360 度航向 以使 A 点的物体面向 B 点 现在 我不确定如何实现这一目标 我用谷歌搜索但没有找到任何好的解决方案 在任何情况下 如何计算二维空间中从 A 点到 B 点的
  • 使用 boost 几何检查两条线是否有交点

    是否可以使用 boost geometry 检查两条线段 每条线段由二维中的两个点给出 是否彼此相交 如果可能的话 boost geometry 是否还允许检查特殊情况 例如另一条线上只有一个点 数字上 或者两条线相等 如果你具体谈论Boo
  • 如何检查一个盒子是否适合另一个盒子(允许任何旋转)

    假设我有两个盒子 每个盒子都是一个长方体 http en wikipedia org wiki Rectangular cuboid aka长方体 我需要编写一个函数来决定盒子是否具有尺寸 一 二 三 可以装入具有尺寸的盒子中 甲 乙 丙
  • 以一定角度遍历二维数组

    通常我们按行或列遍历数组 但这里我想以角度遍历它 我会尝试解释我的意思 因此 假设角度是 45 度 那么它会搜索为 0 0 then 0 1 1 0 then 0 2 1 1 2 0 等等 抱歉 无法上传图像 因为我是新用户 不允许这样做
  • 按度数在圆上找到一个点?

    假设我们有一个 100x100 坐标系 如下所示 0 0 是它的左上角 50 50 是它的中心点 100 100 是它的右下角 等等 现在我们需要从中心向外画一条线 我们知道线的角度 但需要计算其终点的坐标 您认为最好的方法是什么 例如 如
  • Three.js :face4 生成三角形而不是正方形

    我正在尝试使用 tree js 自定义几何图形生成一个正方形 但是这段代码 var cubeGeo new THREE Geometry cubeGeo vertices push new THREE Vector3 25 25 25 cu
  • 找出圆周上像素坐标的算法

    如果我知道圆心 圆半径和垂直角的像素坐标 如何找出圆圆周上一定角度的像素值 基本上 我试图在不同的时间绘制时钟的指针 1点 2点等 Let h是浮点数形式的小时 h 2 25将是 02 15 等 在 0 到 12 之间 cX cY 是中心的
  • 如何从一组重叠的圆计算多边形集?

    这个问题是一些计算细节的扩展这个问题 https stackoverflow com questions 1667310 combined area of overlapping circles 假设有一组 可能重叠的 圆 并且希望计算这组
  • 包围一组点的多边形

    我有一组 S 点 2D 由 x 和 y 定义 我想找到 P 包围该组所有点的最小 含义 具有最少数量的点 多边形 P 是S 有没有已知的算法来计算这个 我在这个领域缺乏文化令人惊讶 感谢您的帮助 对于这个问题有很多算法 它被称为 最小边界框
  • 谷歌地图颤动检查点是否在多边形内

    我正在使用 google maps flutter 插件开发 flutter 项目 我想检查用户位置是否位于我在地图上创建的多边形内 有一个简单的方法使用 JavaScript api con tainsLocation 方法 但对于 fl
  • 用 tkinter 画圆更简单的方法?

    在a上画一个圆tkinter Canvas通常由create oval方法 然而 提供边界框通常是绘制圆的一种令人困惑的方式 想出一个捷径并不是特别困难 但我找不到其他人在做类似的事情 所以我将其发布 希望其他人发现它有用 这是一个称为猴子
  • 计算移动的球与移动的线/多边形碰撞的时间(2D)

    我有一个多边形 里面有一个移动的球 如果球撞到边界 它应该反弹回来 My current solution I split the polygon in lines and calculate when the ball hits the
  • 从基本矩阵中查找单应矩阵

    我正在尝试计算单应性矩阵H给定一组对应关系和基本矩阵F 根据对极几何原理 我知道这可以通过对极线和对极线的叉积来完成F from 极点几何 http www cs unc edu marc tutorial node44 html e ij
  • 帮我用光线追踪器解决这个错误

    我不会针对这个问题发布任何代码 因为它需要太多的上下文 但我将从概念上解释我正在做什么 我正在构建一个使用仿射变换的简单光线追踪器 我的意思是 我将来自相机坐标的所有光线与通用形状相交 这些形状都具有关联的仿射变换 并且光线在与场景对象相交
  • 如何找到给定顶点的所有多边形?

    我有一个顶点列表 并且我知道它们之间的连接 我试图找到顶点的所有多边形形状 这些多边形形状不应重叠 我做了一些研究 我认为如果我可以顺时针 或逆时针 没有区别 遍历顶点 我可以检测多边形形状 因此 我寻找顺时针遍历顶点的解决方案 我发现了一
  • 二维空间中的重叠线段

    我需要找出两条线是否相互重叠 如果两条线平行 我有返回 0 的交集代码 但接下来我需要知道这两条平行线是否重叠 Edit A C B D 1号线 A B 2号线 C D 我需要确定第 1 行是否与第 2 行重叠 但两条线的斜率都可以 gt

随机推荐