0

I have line, or trajectory in 3D space. I also have a 2D shape. I want to take this shape and move it along the curve keeping the surface normal parallel to the tangent of the curve. Based on a post here I have successfully done this that produces something which 'looks right' for shapes with rotational symmetry like a circle. See the code and figure below for the example.

% 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

Note that this code makes use of the Shape Language Modelling functions from the Matlab file exchange to make the curve and get it's tangent at various points, but this isn't crucial to the problem.

However, as you can see, the rotation of the shape flips as you move around the curve with this method. I need to keep the rotation of the shape consistent as I actually wish to sample values from scattered 3D data on the shape surface which represents the inside of a 'tube' or whatever the shape is.

So how can I control the orientation of my shape as I move along the curve?

crobar
  • 2,810
  • 4
  • 28
  • 46

1 Answers1

0

You need 2 vectors and position! The tangent (you have it) and one vector to align to like up which must be not parallel to tangent. Then just construct 3D transform matrix use tangent as Z-axis and exploit the cross product to get the other two for example:

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

Position is just the actual position at the trajectory +/- shape offset. You can adjust the sign of the X,Y,Z axises by negating them or by changing the cross product operand order to obtain the mirroring of shape you want. Now to construct the transform matrix see:

Now just transform/render your shape with this matrix.

Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380
  • Thanks, I'm working on fully understanding your answer, I'm wondering how to best chose `Up`. I'm also feeling like maybe `Up` has to change on every point on the trajectory? – crobar Jul 25 '16 at 10:28
  • 1
    @crobar no it doesn't ... for example the `up` can be the axis of your helix the trajectory is swinging around. The cross products do the align changing for you on its own. This is usually used to obtain NEH (North East Height) coordinate system in aviation applications and or surface navigations. The reference vector can be anything like North, To Sun, To light source, To observer etc. It just must not be paralel to the tangent. To avoid it I usually have 2 such vectors and chose the one that has smaller dot product ... – Spektre Jul 25 '16 at 11:19
  • Thanks, your comment clarifies a few things for me, esp. using two vectors and choosing between them. – crobar Jul 25 '16 at 15:11
  • 1
    Having played around, I might add that the X, Y and Z must all be unit vectors or else your points are also [scaled](https://en.wikipedia.org/wiki/Scaling_(geometry)), which isn't explicitly made clear in the answer. – crobar Jul 26 '16 at 07:13