How to get "Clean" edges on a surface plot?
85 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Kylen
am 2 Aug. 2024 um 21:46
Kommentiert: Kylen
am 6 Aug. 2024 um 17:50
Hello All,
I am trying to plot a surface using the surf() command with some imported shape data from a CSV. The shape in question is created by revolving our data from 0 to 180 degrees. The data starts out as axial position and a corresponding radius. Essentially, it's a half-pipe with asymmetrically tapered ends.
I've been able to import my data, revolve it, and use meshgrid() and griddata() to create the Z coordinate matrix. However, as you can see from my attached screenshot, there are "flats" at the ends of the revolved shape. I have a feeling this has something to do with the interpolation, but I'm not very familiar with this type of stuff. I can't seem to get rid of the flat protrusions.
In my attempts to rectify this, the closest I could get was ending up with jagged edges instead. But this won't work either since this shape data is going to be imported into a Simscape model, and we want it to be as true to life as possible (no flat protrusions and no jagged edges).
Any ideas? Data attached as a text file (wouldn't let me attach a CSV) and code pasted below.
Thanks Everyone!
GS = readtable('GSDataEdited.txt');
GS = table2array(GS);
GSx = GS(:, 1);
GSrad = GS(:, 2);
% Define the angle step (in degrees)
angle_step = 7.5;
all_points = [];
% Loop through angles from 0 to 180 degrees
for angle = 0:angle_step:180
% Convert angle to radians
theta = deg2rad(angle);
% Create rotation matrix for current angle
R = [1 0 0; 0 cos(theta) -sin(theta); 0 sin(theta) cos(theta)];
% Rotate the coordinates
rotated_coords = R * [GSx'; GSrad'; zeros(size(GSx'))];
% Append the rotated coordinates to the matrix
all_points = [all_points, rotated_coords];
end
all_points = all_points';
GSx = all_points(:, 1);
GSy = all_points(:, 2);
GSz = all_points(:, 3);
GSall = [GSx,GSy,GSz;GSx,GSy,-GSz];
GSall = unique(GSall, 'rows');
% Define grid for interpolation
[GSX,GSY] = meshgrid(min(GSx):1:max(GSx), min(GSy):1:max(GSy)); % Define the grid spacing
% Interpolate data onto grid
ZVect = griddata(GSx, GSy, GSz, GSX, GSY, 'linear');
XVect = GSX(1, :);
YVect = GSY(:, 1);
ZVect(isnan(ZVect))=0;
surf(XVect, YVect, ZVect, 'EdgeColor', 'none')
2 Kommentare
Jonas
am 5 Aug. 2024 um 6:31
i am not exactly sure what you want not to appear, amybe one of the two versions below is what you are searching for
GS = readtable('GSDataEdited.txt');
GS = table2array(GS);
GSx = GS(:, 1);
GSrad = GS(:, 2);
% Define the angle step (in degrees)
angle_step = 7.5;
all_points = [];
% Loop through angles from 0 to 180 degrees
for angle = 0:angle_step:180
% Convert angle to radians
theta = deg2rad(angle);
% Create rotation matrix for current angle
R = [1 0 0; 0 cos(theta) -sin(theta); 0 sin(theta) cos(theta)];
% Rotate the coordinates
rotated_coords = R * [GSx'; GSrad'; zeros(size(GSx'))];
% Append the rotated coordinates to the matrix
all_points = [all_points, rotated_coords];
end
all_points = all_points';
GSx = all_points(:, 1);
GSy = all_points(:, 2);
GSz = all_points(:, 3);
GSall = [GSx,GSy,GSz;GSx,GSy,-GSz];
GSall = unique(GSall, 'rows');
% Define grid for interpolation
[GSX,GSY] = meshgrid(min(GSx):1:max(GSx), min(GSy):1:max(GSy)); % Define the grid spacing
% Interpolate data onto grid
ZVect = griddata(GSx, GSy, GSz, GSX, GSY, 'linear');
XVect = GSX(1, :);
YVect = GSY(:, 1);
ZVect(isnan(ZVect))=0;
% a more technical view, such that you can see the mesh only
figure;
surf(XVect, YVect, ZVect, 'FaceColor','none');
% a more smooth experience
figure;
surf(XVect, YVect, ZVect, 'EdgeColor', 'none','FaceColor','interp')
Akzeptierte Antwort
Adam Danz
am 6 Aug. 2024 um 15:05
Bearbeitet: Adam Danz
am 6 Aug. 2024 um 15:08
Conversion from 3D scatter points to a surface is not straightforward. Here, I'm using Delaunay triangulation to create a mesh of triangles that approximates the surface defined by the scatter points.
Code from OP
GS = [0,0
0.225,2.35
1.325,5.525
2.405,7.3375
3.805,9.15
5.76,11.3125
7.45,12.95
9.35,14.5
11.855,16.0875
14.375,17.325
16.035,18.025
18.495,18.9125
21.22,19.6875
24.095,20.2375
27.14,20.5375
29.575,20.6125
32.495,20.625
32.5,20.625
101,20.625
106,20.625
117.225,20.4125
125.15,20.025
133.785,19.425
138.675,18.9875
145.53,18.1375
152.38,16.7
157.47,15.1
160.775,13.8375
164.645,12.1875
169.765,9.8125
174.14,7.6
177.11,5.9125
178.795,4.8375
180.225,3.85
181.895,2.35];
% GS = table2array(GS);
GSx = GS(:, 1);
GSrad = GS(:, 2);
% Define the angle step (in degrees)
angle_step = 7.5;
all_points = [];
% Loop through angles from 0 to 180 degrees
for angle = 0:angle_step:180
% Convert angle to radians
theta = deg2rad(angle);
% Create rotation matrix for current angle
R = [1 0 0; 0 cos(theta) -sin(theta); 0 sin(theta) cos(theta)];
% Rotate the coordinates
rotated_coords = R * [GSx'; GSrad'; zeros(size(GSx'))];
% Append the rotated coordinates to the matrix
all_points = [all_points, rotated_coords];
end
Show the scatter points
plot3(all_points(1,:), all_points(2,:), all_points(3,:),'k*')
axis equal
Triangulate and plot the surface
x = all_points(1,:);
y = all_points(2,:);
z = all_points(3,:);
figure()
tri = delaunay(x,y);
h = trisurf(tri, x, y, z, 'EdgeColor','none','FaceColor','interp');
axis equal
You can play around with it to get different coloration,
figure
h = trisurf(tri, x, y, z,'EdgeColor','none','FaceColor',[.5 .5 .5]);
axis equal
camlight
material dull
3 Kommentare
Adam Danz
am 6 Aug. 2024 um 17:21
Now I see why you were using griddata.
I don't have experience with simscape's modeling graphics. Continuing with your griddata work, the parts of the grid you want to remove are on a single plane at the bottom. If simscape's modeling graphics accepts NaN values, you could fill in those corner values with NaNs. Some MATLAB graphics functions ignore NaN values. To identify those values, I'd start by using inpolygon which determines what coordinates are within a polygon. The polygon boundary would be defined by your GS coordinates.
Weitere Antworten (1)
Adam Danz
am 5 Aug. 2024 um 14:25
Code from OP
GS = [0,0
0.225,2.35
1.325,5.525
2.405,7.3375
3.805,9.15
5.76,11.3125
7.45,12.95
9.35,14.5
11.855,16.0875
14.375,17.325
16.035,18.025
18.495,18.9125
21.22,19.6875
24.095,20.2375
27.14,20.5375
29.575,20.6125
32.495,20.625
32.5,20.625
101,20.625
106,20.625
117.225,20.4125
125.15,20.025
133.785,19.425
138.675,18.9875
145.53,18.1375
152.38,16.7
157.47,15.1
160.775,13.8375
164.645,12.1875
169.765,9.8125
174.14,7.6
177.11,5.9125
178.795,4.8375
180.225,3.85
181.895,2.35];
% GS = table2array(GS);
GSx = GS(:, 1);
GSrad = GS(:, 2);
% Define the angle step (in degrees)
angle_step = 7.5;
all_points = [];
% Loop through angles from 0 to 180 degrees
for angle = 0:angle_step:180
% Convert angle to radians
theta = deg2rad(angle);
% Create rotation matrix for current angle
R = [1 0 0; 0 cos(theta) -sin(theta); 0 sin(theta) cos(theta)];
% Rotate the coordinates
rotated_coords = R * [GSx'; GSrad'; zeros(size(GSx'))];
% Append the rotated coordinates to the matrix
all_points = [all_points, rotated_coords];
end
all_points = all_points';
GSx = all_points(:, 1);
GSy = all_points(:, 2);
GSz = all_points(:, 3);
GSall = [GSx,GSy,GSz;GSx,GSy,-GSz];
GSall = unique(GSall, 'rows');
% Define grid for interpolation
[GSX,GSY] = meshgrid(min(GSx):1:max(GSx), min(GSy):1:max(GSy)); % Define the grid spacing
% Interpolate data onto grid
ZVect = griddata(GSx, GSy, GSz, GSX, GSY, 'linear');
XVect = GSX(1, :);
YVect = GSY(:, 1);
Zorig = ZVect;
ZVect(isnan(ZVect))=0;
Perform convex hull and plot results
k = convhull(GSX,GSY,ZVect,'Simplify',true);
trisurf(k,GSX,GSY,ZVect,'EdgeColor','none','FaceColor', 'interp')
axis padded
Siehe auch
Kategorien
Mehr zu Interpolation finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!