Home Ordered Isoline Calculation from 3D Triangular Surface in MATLAB
Reply: 0

Ordered Isoline Calculation from 3D Triangular Surface in MATLAB

M.Thomas
1#
M.Thomas Published in 2018-01-12 12:54:45Z

I need to extract the isoline coordinates of a 4D variable from a 3D surface defined using a triangulated mesh in MATLAB. I need the isoline coordinates to be a ordered in such a manner that if they were followed in order they would trace the path i.e. the order of the points a 3D printer would follow.

I have found a function that can calculate the coordinates of these isolines (see Isoline function here) but the problem is this function does not consider the isolines to be joined in the correct order and is instead a series of 2 points separated by a Nan value. This makes this function only suitable for visualisation purposes and not the path to follow.

Here is a MWE of the problem of a simplified problem, the surface I'm applying it too is much more complex and I cannot share it. Where x, y and z are nodes, with TRI providing the element connectivity list and v is the variable of which I want the isolines extracted from and is not equal to z.

If anyone has any idea on either.....

  1. A function to extract isoline values in the correct order for a 3D tri mesh.
  2. How to sort the data given by the function Isoline so that they are in the correct order.

.... it would be very much appreciated.

Here is the MWE,

% Create coordinates
[x y] = meshgrid( -10:0.5:10, -10:0.5:10 );
z = (x.^2 + y.^2)/20;    % Z height
v = x+y;            % 4th dimension value

% Reshape coordinates into list to be converted to tri mesh
x = reshape(x,[],1); y = reshape(y,[],1); z = reshape(z,[],1); v = reshape(v,[],1);
TRI = delaunay(x,y);    % Convertion to a tri mesh

% This function calculates the isoline coordinates
[xTows, yTows, zTows] = IsoLine( {TRI,[x, y, z]}, v, -18:2:18);

% Plotting
figure(1); clf(1)
subplot(1,2,1)
trisurf(TRI,x,y,z,v)
hold on
for i = 1:size(xTows,1)
    plot3( xTows{i,1}, yTows{i,1}, zTows{i,1}, '-k')
end
hold off
shading interp
xlabel('x'); ylabel('y'); zlabel('z'); title('Isolines'), axis equal

%% This section is solely to show that the isolines are not in order
for i = 1:size(xTows,1)

    % Arranging data into colums and getting rid of Nans that appear
    xb = xTows{i,1}; yb = yTows{i,1}; zb = zTows{i,1}; 
    xb = reshape(xb, 3, [])'; xb(:,3) = [];
    yb = reshape(yb, 3, [])'; yb(:,3) = [];
    zb = reshape(zb, 3, [])'; zb(:,3) = [];

    subplot(1,2,2)
    trisurf(TRI,x,y,z,v)
    shading interp
    view(2)
    xlabel('x'); ylabel('y'); zlabel('z'); title('Plotting Isolines in Order')
    axis equal; axis tight; hold on
    for i = 1:size(xb,1)
        plot3( [xb(i,1) xb(i,2)], [yb(i,1) yb(i,2)], [zb(i,1) zb(i,2)], '-k')
        drawnow
    end
end

and here is the function Isoline, which I have slightly adpated.

function [xTows, yTows, zTows] = IsoLine(Surf,F,V,Col)

if length(Surf)==3                % convert mesh to triangulation
  P = [Surf{1}(:) Surf{2}(:) Surf{3}(:)];
  Surf{1}(end,:) = 1i;
  Surf{1}(:,end) = 1i;
  i = find(~imag(Surf{1}(:)));
  n = size(Surf{1},1);
  T = [i i+1 i+n; i+1 i+n+1 i+n];
else
  T = Surf{1};
  P = Surf{2};
end
f = F(T(:));
if nargin==2
  V = linspace(min(f),max(f),22);
  V = V(2:end-1);
elseif numel(V)==1
  V = linspace(min(f),max(f),V+2);
  V = V(2:end-1);
end
if nargin<4
  Col = 'k';
end
H = NaN + V(:);
q = [1:3 1:3];
% -------------------------------------------------------------------------

% Loop over iso-values ----------------------------------------------------
xTows = [];
yTows = [];
zTows = [];
for k = 1:numel(V)
  R = {[],[]};
  G = F(T) - V(k);   
  C = 1./(1-G./G(:,[2 3 1]));
  f = unique(T(~isfinite(C))); % remove degeneracies by random perturbation
  F(f) = F(f).*(1+1e-12*rand(size(F(f)))) + 1e-12*rand(size(F(f)));
  G = F(T) - V(k);
  C = 1./(1-G./G(:,[2 3 1]));
  C(C<0|C>1) = -1;
  % process active triangles
  for i = 1:3
    f = any(C>=0,2) & C(:,i)<0;
    for j = i+1:i+2
      w = C(f,q([j j j]));
      R{j-i} = [R{j-i}; w.*P(T(f,q(j)),:)+(1-w).*P(T(f,q(j+1)),:)];
    end
  end
  % define isoline
  for i = 1:3
    X{i} = [R{1}(:,i) R{2}(:,i) nan+R{1}(:,i)]';
%     X{i} = [R{1}(:,i) R{2}(:,i)]';    % Changed by Matt
    X{i} = X{i}(:)';
  end
  % plot isoline
  if ~isempty(R{1})
%     hold on
%     H(k) = plot3(X{1},X{2},X{3},Col);

    % Added by M.Thomas
    xTows{k,1} = X{1};
    yTows{k,1} = X{2};
    zTows{k,1} = X{3};

  end
end

What you will notice is that the isolines (xTows, yTows and zTows) are not in order there "jump around" when plotted sequentially. I need to sort the tows so that they give a smooth plot in order.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.301058 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO