2016-07-22 46 views
0

我有三维空间中的线或轨迹。我也有2D形状。我想采取这种形状,并沿曲线移动它,使曲面的法线与曲线的正切平行。基于一个职位here我已经成功地完成了这项工作,它产生了一些像旋转对称一样的圆形形状的“看起来很合适”的东西。请参阅下面的示例代码和图。将3D形状面与3D轨迹法线对齐

% create data 
npts = 30; 
tend = 8*pi; 
t = linspace(0,tend,npts)'; 
z = linspace(-1,1,npts)'; 
omz = sqrt(1-z.^2); 
x = cos(t).*omz; 
y = sin(t).*omz; 

scatter3 (x,y,z, 'x'); 

hold on 
% fit 3 slms to data in each direction 

xslm = slmengine (t, x, 'knots', ceil(npts/1.5)); 
yslm = slmengine (t, y, 'knots', ceil(npts/1.5)); 
zslm = slmengine (t, z, 'knots', ceil(npts/1.5)); 

% test points 
tq = linspace(0,tend,200 * npts)'; 

dx = slmeval (t, xslm, 1, false); 
dy = slmeval (t, yslm, 1, false); 
dz = slmeval (t, zslm, 1, false); 

quiver3(x,y,z,dx,dy,dz); 

plot3 (slmeval(tq, xslm, 0, false), slmeval(tq, yslm, 0, false), slmeval(tq, zslm, 0, false)); 

hold off 

axis equal 

% The following taken from post on matlab central 
% 
% http://uk.mathworks.com/matlabcentral/newsreader/view_thread/159522 
% 

% P10 = P1-P0; 
% 
% P20 = P2-P0; 

% N = dot(P10,P10)*P20-dot(P20,P20)*P10; % <-- Approx. tangent direction 

R = 0.05; 

P0 = [x,y,z]; 

N = [dx, dy, dz]; 

% circle points 
% theta = linspace(0,2*pi).'; 
box_x = [ -R; R; R; -R; -R ]; 
box_y = [ -R/2; -R; R; R/2; -R/2 ]; 

for ind = 1:size(P0,1) 

    T = null(N(ind,:)).'; % Get two orthogonal unit vectors which are orthog. to N 

%  V = bsxfun (@plus, ... 
%     R * (cos(theta) * T(1,:) + sin(theta) * T(2,:)), ... 
%     P0(ind,:)); 

    V = bsxfun (@plus, ... 
       box_x * T(1,:) + box_y * T(2,:), ... 
       P0(ind,:)); 

    hold on 
    quiver3(P0(ind,1),P0(ind,2),P0(ind,3),T(1,1),T(1,2),T(1,3), 0.5, 'b'); 
    quiver3(P0(ind,1),P0(ind,2),P0(ind,3),T(2,1),T(2,2),T(2,3), 0.5, 'b'); 
    plot3(V(:,1),V(:,2),V(:,3)); 
    hold off 

end 

best attempt

注意,此代码利用了从MATLAB文件交换Shape Language Modelling功能,使曲线,并得到它的不同点切线,但是这并不是问题的关键。

但是,您可以看到,使用此方法移动曲线时,形状的旋转会翻转。我需要保持形状的旋转一致,因为我实际上希望从表示“管”内部的形状表面或任何形状的散射3D数据中采样数值。

所以当我沿曲线移动时,如何控制形状的方向?

回答

0

你需要2个向量和位置! tangent(你有它)和一个向量对齐像up,它必须不平行于切线。然后,只需构建3D变换矩阵利用切线作为Z-axis和利用的叉积以获得其它两个例如:

Up = (0,1,0) 
Z = tangent/|tangent| 
X = cross(Z,Up) 
Y = cross(X,Z) 
O = position 

位置正好在轨迹+/-形状偏移的实际位置。您可以通过取消它们或通过更改交叉积操作数顺序来调整X,Y,Z轴的符号,以获得所需形状的镜像。我们构建变换矩阵看:

现在只是变换/渲染你的形状与此矩阵。

+0

谢谢,我正在努力完全理解你的答案,我想知道如何最好地选择'上'。我也有可能感觉到'上升'必须改变轨迹上的每一点? – crobar

+1

@crobar不,它不会......例如,'up'可以是你的螺旋线的轴线,轨迹是摆动的。交叉产品自行改变你的排列方式。这通常用于在航空应用和/或表面导航中获得NEH(东北高度)坐标系统。参考矢量可以是任何东西,如北,太阳,光源,观察者等。它只是不能平行于切线。为了避免它,我通常有2个这样的向量,并选择了一个小点积... – Spektre

+0

谢谢,你的意见澄清了几件事情,特别是我。使用两个向量并在它们之间选择。 – crobar