2017-06-28 54 views
1

我目前有代碼可以生成分割點,並且在每個分割點將在點周圍的短圓柱體內生成一些點(在3D中,分割位置全部具有0.0F的az值我想有不同的z值在一行中 - 即它仍然在一行中,但例如在z = 3x的行中),但x和y是隨機的。然而,目前所有生成的點都位於面向上的圓柱體中,我希望能夠旋轉這些點,使它們「生成」的圓柱體面向兩個分段之間的方向。 Here's它應該看起來像什麼與它目前看起來像什麼的圖像c# - 關於軸的旋轉點

我發現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; 
} 
+0

我認爲該公式旋轉圍繞原點的段周圍的點,我可能是錯的,但我認爲你想旋轉你的當前段的位置。嘗試簡化公式[f(x,y,z,a,b,c,u,v,w,θ)](https://sites.google.com/site/glennmurray/Home/rotation-matrices-and (a,b,c)是當前分段的位置。 – Poosh

+0

你說得對。該簡化的公式起作用。謝謝! –

+0

很高興幫助! – Poosh

回答

1

Poosh的回答禮貌;

要使用標準化(u^2 + v^2 + w^2 = 1)方向向量繞(a,b,c)線旋轉點(x,y,z)使用以下功能:

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; 
}