2017-06-28 8 views
1

私は現在、セグメントポイントを生成するコードを持っており、各セグメントポイントでポイント周りの短い円柱内にいくつかのポイントを生成します(3Dでは、セグメント位置はすべて0.0Fです私は線の中にあるさまざまなz値を持っていたいと思っています - つまり、線の中にありますが、例えば線z = 3xですが、xとyはランダムです)。現在のところ、生成された点はすべて上向きの円柱上にありますが、「生成された」円柱が2つの線分の間の方向に向くように点を回転させたいのです。 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 -formulas/rotation-about-any-any-axis-in-3-dimension)で、(a、b、c)は現在のセグメント位置です。 – Poosh

+0

あなたはそうです。その単純化された式が機能します。ありがとう! –

+0

助けてくれてうれしい! – Poosh

答えて

1

Pooshの回答礼儀。

normalize(u^2 + v^2 + w^2 = 1)の方向ベクトルを角度thetaで(a、b、c)を通る線について点

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; 
} 
関連する問題