2017-07-06 91 views
0

我一直試圖在3D空間中沿着光盤的位置和法線生成沿着2D光盤(包括平移和旋轉)的圓環的點。數學 - 3D空間中旋轉的2D光盤的生成點

我一直在使用下面的代碼來生成點,在Matlab一直在測試它(但在C#將利用這一點),以檢查點正確生成,但它似乎並沒有被生成點正確。

numPoints = 25; 
radius = 1; 
pos = [1; 2; 3]; 
dir = normc([3; 4; 6]); % normalised 

function [pointsT, points] = GenerateDiscPoints(numPoints, radius, pos, dir) 
    points = zeros(numPoints, 3); 
    pointsT = zeros(numPoints, 3); 

    % Angle between points 
    angle = 2 * pi/numPoints; 

    for i = 1:numPoints+1 
     % Current point angle 
     theta = angle * i; 

     % Generate point in flat disc (y is vertical axis in Unity) 
     x = radius * cos(theta) + pos(1); 
     y = 0 + pos(2); 
     z = radius * sin(theta) + pos(3); 

     % Save points 
     points(i, 1) = x; 
     points(i, 2) = y; 
     points(i, 3) = z; 

     % Calculate t value to translate points 
     t = (dir(1) * pos(1) - dir(1) * x + dir(2) * pos(2) - dir(2) * y + dir(3) * pos(3) - dir(3) * z)/(dir(1)*dir(1) + dir(2)*dir(2) + dir(3)*dir(3)); 

     % Translate points to correct location 
     xT = x + t*dir(1); 
     yT = y + t*dir(2); 
     zT = z + t*dir(3); 

     % Save translated points 
     pointsT(i, 1) = xT; 
     pointsT(i, 2) = yT; 
     pointsT(i, 3) = zT; 
    end 

    % Plot 
    figure; 
    hold all; 
    grid on; 
    scatter3(points(:,1), points(:,2), points(:,3), 25, 'r'); 
    scatter3(pointsT(:,1), pointsT(:,2), pointsT(:,3), 25, 'g'); 
    p3 = line([pos(1) pos(1)+dir(1)], [pos(2) pos(2)+dir(2)], [pos(3) pos(3)+dir(3)]); 
    set(p3, 'Color', 'blue'); 
end 

Here's a picture of the output.

藍線是正常的光盤,紅點是點被翻譯之前,綠點是被翻譯後的點。據我的眼睛看來,翻譯後的點似乎不是在具有正常指定的光盤中產生的。

我現在的算法有什麼問題?更好的方法是什麼?

+0

的[繪製的法向矢量在Matlab的平面(https://stackoverflow.com/questions/35082373/plotting-a-normal-vector-to-a-plane-可能的複製in-matlab) – dasdingonesin

+0

你的軸縮放讓它看起來不對。使用['axis equal'](https://de.mathworks.com/help/matlab/ref/axis.html#inputarg_style) – dasdingonesin

+0

我並不瞭解axis equal。使用它使圖表看起來正確,但我相信@spug說的是正確的。我的代碼只產生點的投影,因此它會生成一個橢圓而不是一個圓。 –

回答

1

沿dir方向A簡單線性平移不足 - 您會在pos與平面上的圓的投影結束與正常dir,即橢圓形。

你既可以:

  • pos構造一個正交基,其中一個軸是dir

    簡單的方法來做到這一點:

    1. 檢查X軸平行於dir - 最好是做abs(dot(dir, X)) < 0.8(假設都是歸一化),所以他們不是太接近對方

    2. 如果(1)爲真,則採取dir2 = Y,否則dir2 = X

    3. 創建第一個基礎矢量,A = normalize(cross(dir, dir2))

    4. 創建第二個,B = cross(dir, A)。現在

    5. 可以生成在由pos + radius * (A * cos(theta) + B * sin(theta))theta的每個值的點(在矢量表示法)。

+0

如果我想要一個不同的半徑值,它最終會變成'pos + A * radius * cos(theta)+ B * radius * sin(theta)'? –

+0

@bradleygray對不起,我忘了把它放進去 – meowgoesthedog