3D Surface of revolution from a 2D perimeter

31 visualizzazioni (ultimi 30 giorni)
Claud il 31 Mar 2023
Commentato: Claud il 1 Apr 2023
Hi everyone,
I am trying to create a surface of revolution with respect to the y-axis of the 2D geometry I have plotted in the attached image. To do so, I have generated the arrays of the x- and y-values of the lines that I used to plot the contours for the 2D geometry (considering only the quadrants where x>0 such that it can be rotated by 360° to obtain a closed geometry). However, I am struggling to find a simple method to create the surface of rotations for all the closed segments and to merge the results into an stl file. For example, the circles should become tori, the rectangular payload should become a cylinder, and the overall shape should be that of a HIAD (as indicated in the image attached). I also attached the script with the x- and y- arrays for each closed set of curves.
I would appreciate any help
2 CommentiMostra NessunoNascondi Nessuno
John D'Errico il 31 Mar 2023
Pretty simple, actually. Do you want triangles? Or quad elements?
Claud il 31 Mar 2023
Quads would be ideal if possible!

Accedi per commentare.

Risposta accettata

John D'Errico il 1 Apr 2023
Modificato: John D'Errico il 1 Apr 2023
Ok. (I should probably write code to do this in general, for any arbitrary polygon.)
Quad elements. I'll show how to do it for a circle, in the (x,y) plane, then rotated around the x axis.
nt = 100;
t = linspace(0,2*pi,nt).'; % I want this as a column vector
C = [2 3]; % the center of the circle in the (x,y) plane.
R = 1; % radius 1
xy = C + R*[cos(t), sin(t)]; % points in the circle
plot(xy(:,1),xy(:,2),'r-')
axis equal % makes it show up as a circle
nphi = 200; % 100 elements around the axis.
phi = linspace(0,2*pi,nphi + 1); % 100 elements means that we need to have 101 points in the surface of revolution
Next, we need to create a 2-d mesh. I'll use ndgrid. meshgrid would work too. The mesh will be parameterized in terms of t and phi.
[T,PHI] = ndgrid(t,phi);
[subt,subphi] = ndgrid(1:nt-1,1:nphi-1);
ind = sub2ind([nt,nphi],subt,subphi);
ind = ind(:);
rectess = [ind,ind+1,ind+nt,ind+nt+1]; % quad elements
Now build the nodes in (x,y,z), by rotating the circle around the x axis.
X = (C(1)+R*cos(T)).*cos(PHI); % Multiply the original x by cos(phi)
Y = (C(2)+R*sin(T)); % Leave Y alone
Z = (C(1)+R*cos(T)).*sin(PHI); % Multiply the original x by sin(phi) to create the Z component
surf(X,Y,Z)
axis equal
box on
xlabel X
ylabel Y
zlabel Z
So, a circle in the (x,y) plane, rotated around the x-axis. Each row of rectess corresponds to one quad element. The only problem that remains is the nodes should wrap around. Essentially, we have nodes that are repeated in that tessellation. The first quad element in the list was:
rectess(1,:)
ans = 1×4
1 2 101 102
But some of the quads need to be fixed, because the first node in the circle is also the last node. To make this a valid tessellation, without those duplicated elements, we need to treat those duplicated nodes properly.
[R,C] = ind2sub([nt,nphi],rectess);
R(R == nt) = 1;
C(C == nphi) = 1;
rectess = sub2ind([nt,nphi],R,C);
And now the last quad element in the list is:
rectess(end,:)
ans = 1×4
19899 19801 99 1
That should work.
3 CommentiMostra 1 commento meno recenteNascondi 1 commento meno recente
John D'Errico il 1 Apr 2023
Modificato: John D'Errico il 1 Apr 2023
Clearly you do not understand the idea. Read my answer carefully, and think about what I wrote. I did point out what you need to do.
Given a set of points in a plane...
xy = [1 1;5 2;3 4;2 3;1 1];
plot(xy(:,1),xy(:,2),'-o')
Is that fully arbitrary enough for you?
Now, rotate them around the x axis. Or the y axis. Or the z axis. First, the x axis.
If you rotate around the x axis, then effectively we are working in a cylindrical coordinate system, where y and z will be treated as the polar coordinate part. Effectively, a cylindrical coordinate system is Cartesian in one variable, and polar in the other variables.
nphi = 100;
phi = linspace(0,2*pi,nphi);
X = xy(:,1)*ones(1,nphi); % x stays unchanged
Y = xy(:,2)*cos(phi); % y is multiplied by cos(phi)
Z = xy(:,2)*sin(phi); % z is the original y, times sin(phi)
surf(Y,X,Z) % As I constructed the arrays, surf flips the axes
xlabel X
ylabel Y
zlabel Z
axis equal
box on
grid on
title 'Rotation around the X axis'
Do you see that? Nothing difficult to write. One can build quad elements from the surface. I showed how to do that.
Rotation around the y axis is as trivial. Must I do that? Rotating around the y axis is identical in nature.
X = xy(:,1)*cos(phi);
Y = xy(:,2)*ones(1,nphi);
Z = xy(:,1)*sin(phi);
surf(Y,X,Z)
xlabel X
ylabel Y
zlabel Z
axis equal
box on
grid on
title 'Rotation around the Y axis'
Finally, since all of the points started in the (x,y) plane, you cannot create a volume by rotating around the z axis.
The surface itself is composed of entirely quad elements, though for these objects I've not constructed the tessellations. It would be just a list of numbers, and I did that in my answer.
Claud il 1 Apr 2023
Thank you very much, you have been extremely helpful. I now fully understand the idea behind the code.

Accedi per commentare.

Categorie

Scopri di più su Surface and Mesh Plots in Help Center e File Exchange

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by