【问题标题】:c# - Rotating Points About Axisc# - 关于轴的旋转点
【发布时间】:2017-06-28 01:57:38
【问题描述】:

我目前有代码将生成分段点,并且在每个分段点将在该点周围的短圆柱内生成一些点(在 3D 中,分段位置的 z 值都为 0.0F(但是我希望有改变一行中的 z 值 - 即它仍然在一行中,但例如在行中 z = 3x),但 x 和 y 是随机的)。然而,目前生成的所有点都在一个朝上的圆柱体中,我希望能够旋转这些点,使它们“生成”的圆柱体面向两个段之间的方向。 Here's 它应该是什么样子的图像与它当前的样子

我发现了this 类似的关于绕轴旋转点的问题;我接受了答案并将该代码用于我的 RotatePoints() 函数,但它似乎无法正常工作,我不知道为什么。下面是我的伪代码,我需要做什么才能让这个功能正常工作?有一个更好的方法吗?这些点只需要在旋转的圆柱体中生成,那么完全不同的方法会更高效、更容易吗?

我所拥有的只是在本地空间中存储为 Vector3 {x,y,z} 的每个线段和每个点的位置。

伪代码

double radius;
// Generates the positions where the points will be generated around
// These are just the x,y,z positions of the object in world space
Vector3[] segmentLocations = GenerateSegmentPositions(numSegments);

for (int i = 0; i < numSegments; i++) {
    // Generates points in a cylinder facing up the +ve y-axis
    // This works fine        
    Vector3[][] pointsAroundSegment = GeneratePoints(segmentLocations[i], radius);

    if (i != numSegments - 1 && i > 0) {
        // Generate a normalise direction vector for the new direction
        Vector3 newDir = Vector3.Normalise(segmentLocations[i + 1] - segmentLocations[i]);
        double theta = Vector3.AngleBetween(newDir - Vector3.Normalise(segmentLocations[i] - segmentLocations[i - 1]));
        // Rotates points (this currently rotates the points so they 'should' be facing the new direction, I haven't yet modified this to face the halfway point)
        // This doesn't work
        pointsAroundSegment = RotatePoints(pointsAroundSegment, newDir, theta/2);
    } else if (i == numSegments - 1) {
        // Generate final point
        // This works fine
        pointsAboutSegment = GenerateFinalPoint(segmentLocations[i]);
    }
}

// This is the actual rotation function
// RotatePoints() effectively just calls this for each point in the array
public static double[] Rotate(double x, double y, double z, double u, double v, double w, double theta) {
    double[] c = new double[3];
    c [0] = u * (u * x + v * y + w * z) * (1 - Math.Cos (theta)) + x * Math.Cos (theta) + (-w * y + v * z) * Math.Sin (theta);
    c [1] = v * (u * x + v * y + w * z) * (1 - Math.Cos (theta)) + y * Math.Cos (theta) + (w * x - u * z) * Math.Sin (theta);
    c [2] = w * (u * x + v * y + w * z) * (1 - Math.Cos (theta)) + z * Math.Cos (theta) + (-v * x + u * y) * Math.Sin (theta);

    return c;
}

【问题讨论】:

  • 我认为这个方程围绕原点旋转了线段周围的点,我可能是错的,但我认为你想围绕你当前的线段位置旋转。尝试简化公式f(x,y,z,a,b,c,u,v,w,θ),其中 (a,b,c) 是您当前的分段位置。
  • 你是对的。这个简化的公式有效。谢谢!
  • 很高兴有帮助!

标签: c# rotation


【解决方案1】:

回答由 Poosh 提供;

使用归一化的 (u^2 + v^2 + w^2 = 1) 方向向量将点 (x,y,z) 围绕通过 (a,b,c) 的线旋转角度 theta 使用以下函数:

public static double[] Rotate(double x, double y, double z, double a, double b, double c, double nu, double nv, double nw, double theta) {
    double[] rP = new double[3];

    rP [0] = (a * (nv * nv + nw * nw) - nu * (b * nv + c * nw - nu * x - nv * y - nw * z)) * (1 - Math.Cos (theta)) + x * Math.Cos (theta) + (-c * nv + b * nw - nw * y + nv * z) * Math.Sin (theta);
    rP [1] = (b * (nu * nu + nw * nw) - nv * (a * nu + c * nw - nu * x - nv * y - nw * z)) * (1 - Math.Cos (theta)) + y * Math.Cos (theta) + (c * nu - a * nw + nw * x - nu * z) * Math.Sin (theta);
    rP [2] = (c * (nu * nu + nv * nv) - nw * (a * nu + b * nv - nu * x - nv * y - nw * z)) * (1 - Math.Cos (theta)) + z * Math.Cos (theta) + (-b * nu + a * nv - nv * x + nu * y) * Math.Sin (theta);

    return rP;
}

【讨论】:

    猜你喜欢
    • 2010-09-15
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    相关资源
    最近更新 更多