【问题标题】:Math - Generating Point in Rotated 2D Disc in 3D Space数学 - 在 3D 空间中的旋转 2D 圆盘中生成点
【发布时间】:2017-07-06 06:57:25
【问题描述】:

我一直在尝试仅使用圆盘的位置和法线在 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

蓝线是圆盘的法线,红点是平移前的点,绿点是平移后的点。在我看来,翻译点似乎没有在具有指定法线的光盘中生成。

我当前的算法有什么问题?有什么更好的方法来做到这一点?

【问题讨论】:

  • 您的轴缩放使它看起来不对。使用axis equal
  • 我不知道轴相等。使用它使图表看起来正确,但我相信@spug 所说的是正确的。我的代码只生成点的投影,因此它会生成一个椭圆而不是一个圆。

标签: matlab 3d


【解决方案1】:

沿dir 方向的简单线性平移是不够的 - 您最终会在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 的每个值处生成点。

【讨论】:

  • 如果我想要不同的半径值,它最终会是pos + A * radius * cos(theta) + B * radius * sin(theta)?
  • @bradleygray 是的,对不起,我忘了把它放进去
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-19
相关资源
最近更新 更多