c# - 计算围绕一条线的长方体的 Point3Ds

标签 c# algorithm vector-graphics

有两个 Point3D(AB),我想计算围绕直线的长方体 (a,b,c ... h) 的点在 AB 之间,就像一个船体:

enter image description here

有一个自由度,长方体的角度,因为它可以绕AB线旋转。我还不确定这是否是个问题。

我尝试计算垂直于ABD 的向量,然后计算ABAD = <强>E。在代码中,CA - B 所以它的偏移平行于AB

我对这三个向量(CDE 进行了归一化处理,并将其与偏移量相乘以从 中添加/减去它们>AB。它还没有完全起作用。

编辑:查看 ja72 的解决方案代码

我还实现了一种寻找法向量的方法:

                double ax = Vector3D.AngleBetween(E, new Vector3D(1, 0, 0));
                double ay = Vector3D.AngleBetween(E, new Vector3D(0, 1, 0));
                double az = Vector3D.AngleBetween(E, new Vector3D(0, 0, 1));

                ax = Math.Abs(ax - 90);
                ay = Math.Abs(ay - 90);
                az = Math.Abs(az - 90);

                if (ax <= ay & ax <= az)
                {
                    n = Vector3D.CrossProduct(E, new Vector3D(1, 0, 0));
                }
                else if (az <= ax && az <= ay)
                {
                    n = Vector3D.CrossProduct(E, new Vector3D(0, 0, 1));
                }
                else
                {
                    n = Vector3D.CrossProduct(E, new Vector3D(0, 1, 0));
                }
                n = normalize(n);

最佳答案

您需要两个方向向量。一个是沿着 AB 给出的线

Vector3D e = Normalize(B-A)

还有一个描述横截面的“向上”方向。这可以给出,也可以使用以下算法计算(优先于 +y)

if( e.X != 0 || e.Z != 0 ) 
{
    // choose direction perpendicular to line closest to +y direction
    Vector3D n = [-e.X*e.Y, e.X*e.X+e.Z*e.Z, -e.Z*e.Y];
} else {
    // if line along +y already then choose +z for up vector
    Vector3D n = [ 0, 0, 1];
}

现在可以计算出第3个方向组成坐标系

Vector3D k = Normalize( Cross(e,n) )

然后你组装了 3×3 旋转矩阵,将局部坐标转换为世界坐标

    | k.X  n.X  e.X |
R = | k.Y  n.Y  e.Y | 
    | k.Z  n.Z  e.Z |

局部坐标沿线的方向为+z使得

Point3D a = A + R*[w,h,0]
Point3D b = A + R*[-w,h,0]
Point3D c = A + R*[w,-h,0]
Point3D d = A + R*[-w,-h,0]

Point3D e = B + R*[w,h,0]
Point3D f = B + R*[-w,h,0]
Point3D g = B + R*[w,-h,0]
Point3D h = B + R*[-w,-h,0]

其中 R*[x,y,z] 表示矩阵向量乘法,wh 是宽度和高度矩形横截面,AB 是点AB 的位置向量。向量之间的加法是逐个元素的。


我已经检查了我自己的代码中的代码,它可以工作。 vec3 是 3D 向量的别名,mat3 是 3×3 矩阵的别名。

Cube

    vec3 u=(B-A).Normalized();

    vec3 n = vec3.O;
    if(Math.Abs(u.X)<=Math.Abs(u.Y)&&Math.Abs(u.X)<=Math.Abs(u.Z))
    {
        n=new vec3(u.Y*u.Y+u.Z*u.Z, -u.Y*u.X, -u.Z*u.X);
    }
    else if(Math.Abs(u.Y)<=Math.Abs(u.X)&&Math.Abs(u.Y)<=Math.Abs(u.Z))
    {
        n=new vec3(-u.X*u.Y, u.X*u.X+u.Z*u.Z, -u.Z*u.Y);
    }
    else if(Math.Abs(u.Z)<=Math.Abs(u.X)&&Math.Abs(u.Z)<=Math.Abs(u.Y))
    {
        n=new vec3(-u.X*u.Z, -u.Y*u.Z, u.X*u.X+u.Y*u.Y);
    }
    vec3 v=n.Cross(u);

    mat3 R=mat3.Combine(v, n, u);

    var a=A+R*new vec3(wt, ht, 0);
    var b=A+R*new vec3(-wt, ht, 0);
    var c=A+R*new vec3(wt, -ht, 0);
    var d=A+R*new vec3(-wt, -ht, 0);
    var e=B+R*new vec3(wt, ht, 0);
    var f=B+R*new vec3(-wt, ht, 0);
    var g=B+R*new vec3(wt, -ht, 0);
    var h=B+R*new vec3(-wt, -ht, 0);

关于c# - 计算围绕一条线的长方体的 Point3Ds,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21857490/

相关文章:

c# - 使用列表框进行数据绑定(bind)

c# - 为什么在此示例中再次引用事件处理程序?

python - Turtle 模块 - 保存图像

c# - 如何在 C# 中使用反射找到所有实现通用抽象类的类?

c# - Shannon-fano 编码算法 - 较大集合上的奇怪行为

arrays - 在线性时间内迭代嵌套数组

python - 从列表的元素中生成数字

python - 成对计算的高效算法

html - SVG 在 Chrome 中无法正确缩放

WPF 路径与图像 png jpg