How can I plot the surface normal variation of any given surface?
23 views (last 30 days)
Show older comments
I am working on a project in which I have to analyse how complex some surfaces are according to how they vary. The way I am doing it is by analysing the angle of the surface normal in a given scan-path and comparing them to a flat plate, whose surface normals would always be at 90º. Using stlread, I managed to plot the surfaces I had developed in Inventor in Matlab. I then meshed the surfaces using trimesh and DelaunayTriangulation, and from there obtained the surface normals' vectors, as such:
data=stlread('Hemiellipsoid.stl');
figure
[X,Y,Z] = meshgrid(1:4);
x = data.Points(:,1);
y = data.Points(:,2);
z = data.Points(:,3);
DT = delaunayTriangulation(x,y,z);
[T,Xb] = freeBoundary(DT);
TR = triangulation(T,Xb);
P = incenter(TR);
F = faceNormal(TR);
trisurf(T,Xb(:,1),Xb(:,2),Xb(:,3), ...
'FaceColor','cyan','FaceAlpha',0.8);
axis equal
xlabel('X direction');
ylabel('Y direction');
hold on
quiver3(P(:,1),P(:,2),P(:,3), ...
F(:,1),F(:,2),F(:,3),0.5,'Color','r');
Where F gives a matrix with the coordinates for all the surface normals. From here, using simple geometry it is easy to obtain the angles at which they are oriented. However, I need to define a scan path. That is, ideally all surface normals would be equally spaced in such a way that the grid would look like a series of rows and columns, so that I can analyse how the surface varies in any given direction. The way F is output does not allow me to do this, first because there isn't equal spacing between surface normals, and secondly because there is no indication of the order in which these are presented.
The only way I found around this was using surfnorm in a normal surfplot. The issue is that I can't do that with a file imported from Inventor. Does anyone have nay ideas?
Thank you all for your time.
3 Comments
Answers (1)
Avni Agrawal
on 14 May 2024
I understand that you are trying to plot the surface normal variation of any given surface. Certainly, here's a streamlined approach to analyze surface normals from STL data and examine their variation along a defined scan path by interpolating the surface onto a regular grid and calculating normals for it.
% Load STL file and prepare data
data = stlread('Hemiellipsoid.stl');
x = data.Points(:,1);
y = data.Points(:,2);
z = data.Points(:,3);
% Define a regular grid and interpolate Z values onto this grid
[Xq, Yq] = meshgrid(linspace(min(x), max(x), 100), linspace(min(y), max(y), 100));
Zq = griddata(x, y, z, Xq, Yq, 'natural');
% Calculate surface normals for the regular grid
[Nx, Ny, Nz] = surfnorm(Xq, Yq, Zq);
% Plot the interpolated surface and its normals
figure;
mesh(Xq, Yq, Zq); % Interpolated surface
hold on;
quiver3(Xq, Yq, Zq, Nx, Ny, Nz, 0.5, 'r'); % Surface normals
xlabel('X direction'); ylabel('Y direction'); zlabel('Z direction');
% Analyze surface normals along a scan path (e.g., along a specific row)
rowIndex = 50; % Example: 50th row
normalsAlongRow = [Nx(rowIndex, :); Ny(rowIndex, :); Nz(rowIndex, :)]';
angles = acosd(normalsAlongRow(:,3)); % Angles with respect to the Z-axis
This code performs the following steps:
1. Load STL Data: Reads the STL file and extracts the point coordinates.
2. Interpolate onto a Regular Grid: Creates a regular grid covering the extent of the STL data and interpolates Z values onto this grid.
3. Calculate and Plot Surface Normals: Uses `surfnorm` to calculate normals for the interpolated surface and plots these normals.
4. Analyze Normals Along a Scan Path: Selects a row of the grid (as an example scan path) and calculates the angles of the normals along this path with respect to the Z-axis.
This approach allows you to analyze how surface normals vary along a defined path, comparing against a flat plate normal (90º to the surface).
I hope this helps.
0 Comments
See Also
Categories
Find more on Surface and Mesh Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!