java - 圆的 3D 旋转使边缘交叉两点

标签 java math matrix 3d quaternions

我正在尝试使一个圆(实际上是一个扁平圆柱体)旋转,以便边缘穿过世界位置中的两个点。这两个点可以位于球体上的任何位置。球体与圆柱体具有相同的半径和位置。两者的原点都是[0,0,0]。

这有点难以解释,因此我添加了三张图片,希望能够说明我想要实现的目标。

flat cylinder with same origin as encapsulation sphere with rim touching two points

在这里你可以看到我正在努力实现的目标。黄色圆圈代表球体上的一个点,而红色圆圈代表另一个点。蓝线实际上是穿过球体的扁平圆柱体,并进行旋转以穿过两个点。

flat cylinder with same origin as encapsulation sphere with rim touching two points

这是另一张类似的图片,但点位于不同的位置。

flat cylinder with same origin as encapsulation sphere with rim touching two points, the sphere is stripped away

在这张图片中,人们可以看到完整的圆柱体,因为球体已被隐藏。

现在,我的数学真的很糟糕,所以我真的很喜欢由伪代码或编程语言组成的答案。如果我这么幸运的话,java.lang. 圆的旋转可以用四元数或矩阵来表示

到目前为止,我所尝试的是将圆柱体旋转为向上 vector 朝向其中一个点,以及向前 vector 朝向另一点。但我似乎无法让它发挥作用。我还尝试了其他解决方案,其中大多数涉及两次旋转(每个点一次),但最终在组合旋转时遇到了麻烦。

这是我当前的非工作代码:

这段代码使圆经过第一个点,然后用“向上 vector ”将其旋转到同一点,第二次旋转根据第一个点的位置而变化,并且在所有地方都是如此。

//calculate direction vector between the two points
point1point2dir.set(point1Pos);
//subtract point two position
point1point2dir.sub(point2Pos);
//normalize
point1point2dir.nor();

//make two quaternions for rotation
Quaternion rot1=new Quaternion();
Quaternion rot2=new Quaternion();


//set first rotation two a rotation between X-axis and point1 position. Vector3.X = (1,0,0)
rot1.set(m.quatUtils.getRot(Vector3.X, point1Pos));

//crossmuliply direction vector between the two points with X-axis
point1point2dir.crs(Vector3.X);

//set the second rotation to a rotation between Z-Axis and the crossmultiplied direction vector
rot2.set(m.quatUtils.getRot(Vector3.Z, point1point2dir));

//multiply the two rotations
rot1.mul(rot2);

//apply the rotation to the cylinders matrix
cylinderMatrix.rotate(rot1);


//the function that gets the quaternion rotation between two vectors
Quaternion getRot(Vector3 pStart, Vector3 pDest) {
    start.set(pStart);
    dest.set(pDest);

    start.nor();
    dest.nor();

    cosTheta = Vector3.dot(start.x, start.y, start.z, dest.x, dest.y,
            dest.z);
    rotationAxis.set(0.0f, 0.0f, 0.0f);

    if (cosTheta < -1.0f + 0.001f) {

        rotationAxis.set(Z_AXIS);
        rotationAxis.crs(start);

        if (rotationAxis.len2() < 0.01f) {
            rotationAxis.set(X_AXIS);
            rotationAxis.crs(start);
        }

        rotationAxis.nor();
        resultQuat.set(rotationAxis, 180.0f);
        return resultQuat;
    }

    rotationAxis.set(start);
    rotationAxis.crs(dest);

    s = (float) Math.sqrt((1 + cosTheta) * 2);
    invs = 1.0f / s;
    resultQuat.set(rotationAxis.x * invs, rotationAxis.y * invs,
            rotationAxis.z * invs, s * 0.5f);
    return resultQuat;
}

最佳答案

我建议这个解决方案:

  1. 计算 v1v2 作为从球体中心到您希望圆柱体通过槽的每个点的 vector 。

  2. v1v2进行叉积以获得圆柱体的向上 vector ,我们将其称为n.

  3. 将圆柱体的中心定位在球体的中心。

  4. 使用n作为 vector 向上旋转圆柱体。

关于java - 圆的 3D 旋转使边缘交叉两点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28322905/

相关文章:

java - Scoped Variables 和 WeakReferences 奇怪地交互 - 有些对象没有得到垃圾收集

arrays - 我怎样才能最好地压缩部分排序的 50000 字节

R:从 Quanteda DFM、稀疏文档特征矩阵、对象中删除正则表达式?

java - 将 EditText 过滤器设置为自定义范围内的数字

java - Java 中的解析文件和模式检测

java - Intent 不适用于将 fragment 移动到 Activity

c# - 按数量递减将 x 分成 y 部分

math - 弹丸的轨迹遇到移动物体(二维)

c - 编写锯齿形矩阵的程序

matlab - 以符号方式求解矩阵方程