how to create a volume from the revolution of a variable area trapezoid

398 visualizzazioni (ultimi 30 giorni)
I'm looking for the work flow of how to create a volume by revolving a variable area trapezoid around the z axis. I have a formula for the area of the trapezoid and it is a function of the radial distance from the origin. Both the height and this radial distance vary with the angle of revolution.
The figure immediately below shows the elliptical path that the rotation takes. Because the trapezoid area varies with the angle of revolution, the path traced in the x-y plane is an ellipse and not a circle. The figure below shows the path in the x-y plane:
This next figure shows the x-z plane which shows the variable-area trapezoid at phi = 0 degrees and phi = 180 degrees. The rotation occurs around the vertical axis that goes through the point "S". Notice the large reduction in area of the trapezoid.
The radial line length, p, to the ellipse edge is given by,
where θ is a constant value as are w and R. At θ = 45 degrees and R = 0.0006, w = 0.0007908.
NOTE: Figure 2 is not to scale with Fig. 1.
What I am trying to do is to verify an equation that I have developed for calculating this volume. I want to make sure that my equation, in fact, produces the volume of the revolved variable-area trapezoid. The area of the trapezoid is given by
and h is given by:
where B is a constant and is a constant where p is evaluated at ϕ = 90 degrees. For the values of θ, w and R given above, B = 0.867.
The volume then is given by,
The next figure shows an incremental volume diagram which is then integrated as in the equation immediately above,
And so the final result should look something like the blue portion of each drawing below. How would I go about implementing this in Matlab?
  46 Commenti
Robert Demyanovich
Robert Demyanovich circa 7 ore fa
Modificato: Robert Demyanovich circa 7 ore fa
@Matt J and William Rose: Here is a table comparing the different methods for calculating the volume. Again, %difference assumes that the volume calculated by the equation is correct.
Paul
Paul circa 3 ore fa
The only contribution of this comment is to demonstrate how the volume integral can be determined and evaluated using the Symbolic Math Toolbox. In principal, one could also convert the integrand to an anonymous function for use with integral, but I didn't try that.
clearvars
syms r z phi z_u real
syms p(phi)
Define the volume integral. The factor of 2 out front follows from the lower bound of the innermost integral being 0 (as I see it the volume is symmetric around z = 0)
V = 2*int(int(r*int(1,z,0,z_u,'Hold',true),r,0,p(phi),'Hold',true),phi,0,2*sym(pi),'Hold',true)
V = 
Inner integral
I = int(1,z,0,z_u)
I = 
Define the height of the trapezoid, relative to z = 0, as a function of phi and the radial distance
syms h_s h(phi)
z_u = h_s/2 + (h(phi)/2 - h_s/2)/p(phi)*r;
Substitute
I = subs(I)
I = 
Middle integral
I = int(r*I,r,0,p(phi))
I = 
Define h(phi) and substitute, bring in the factor of 2
syms B
h(phi) = B*p(phi);
I = expand(2*subs(I))
I = 
Hence the volume is
V = int(I,phi,0,2*sym(pi))
V = 
Expressions for p(phi) and h(phi)
syms R theta w real
eqn = p(phi)/R == (w*sin(theta)^2*cos(phi)/R + sqrt(sin(phi)^2+sin(theta)^2*cos(phi)^2-w^2/R^2*sin(theta)^2*sin(phi)^2))/(sin(phi)^2+sin(theta)^2*cos(phi)^2)
eqn = 
eqn = isolate(eqn,p)
eqn = 
p(phi) = rhs(eqn);
h(phi) = B*p(phi);
Definition of h_s
h_s = h(sym(pi)/2);
Sub all of the above into the integral
V = subs(V)
V = 
Define the numeric parameters of the problem
thetav = sym(pi)./[12;6;4;3;2];
Rv = 0.0006*ones(5,1);
Bv = [0.2601;0.5384;0.8670;1.2589;1.25];
wv = [0.0022692;0.0011838;0.0007908;0.0005308;0];
Sub in parameters
V = subs(V,{theta,R,w,B},{thetav,Rv,wv,Bv});
Evaluate
V = double(vpa(V));
T = table(thetav,Rv,Bv,wv,V,'VariableNames',{'theta','R','B','w','V'})
T = 5×5 table
theta R B w V _____ ______ ______ _________ __________ pi/12 0.0006 0.2601 0.0022692 2.6555e-09 pi/6 0.0006 0.5384 0.0011838 1.5383e-09 pi/4 0.0006 0.867 0.0007908 1.2907e-09 pi/3 0.0006 1.2589 0.0005308 1.2527e-09 pi/2 0.0006 1.25 0 8.4823e-10

Accedi per commentare.

Risposta accettata

William Rose
William Rose il 17 Ott 2025 alle 18:42
Modificato: William Rose il 20 Ott 2025 alle 18:35
{Edit 10/20/2025: Fix error in code below by changing a 1 to a 3. It was
[hst(1),pt(i,3),pb(i,3),hsb(3),hst(3)],'-r.')
and it should be, and now is
[hst(3),pt(i,3),pb(i,3),hsb(3),hst(3)],'-r.')
}
I like the elegant solution of @Matt J.
You indicate in your comments that you are also interested in solving the problem by explicit rotation of the trapezoid.
Here is code that that generates a wire frame view of the shape, by rotating the trapezoid.
N=40; % number of angular steps in one rotation
w=7.908e-4; R=6e-4; % constants in equation for p(t) [units=length]
B=0.867; % constant in equation for h(t): h(t)=B*p(t) [dimensionless]
dt=2*pi/N; % angle step size [radians]
t=[0:dt:2*pi]'; % angle of rotation (vector, length N+1) [radians]
% Compute p(t):
p=((w/2)*cos(t)+(R^2*(sin(t).^2+0.5*cos(t).^2)-(w^2/2)*sin(t).^2).^0.5)./(sin(t).^2+0.5*cos(t).^2);
h=B*p; % [length]
hs=B*sqrt(R^2-w^2/2);
% Compute arrays of 3D points
pt=[p.*cos(t),p.*sin(t),h/2]; % x,y,z coords of points along top of shape
pb=[p.*cos(t),p.*sin(t),-h/2]; % x,y,z coords of points along bottom of shape
hst=[0,0,hs/2]; hsb=[0,0,-hs/2]; % x,y,z coords of top, bottom central points
% Plot the trapezoid in 3D at various rotation angles
figure; hold on
for i=1:N
plot3([hst(1),pt(i,1),pb(i,1),hsb(1),hst(1)],...
[hst(2),pt(i,2),pb(i,2),hsb(2),hst(2)],...
[hst(3),pt(i,3),pb(i,3),hsb(3),hst(3)],'-r.')
end
plot3(pt(:,1),pt(:,2),pt(:,3),'-g') % curve connecting top points
plot3(pb(:,1),pb(:,2),pb(:,3),'-b') % curve connecting bottom points
xlabel('x'); ylabel('y'); zlabel('z');
hold off; axis equal; grid on; view(-45,25)
If you run the code locally, you will be able to rotate the 3D plot by clicking on the 3D rotate tool at top of the plot, then click and drag inside the plot.
Wrap a surface around the points, compute the volume, plot the surface:
pAll=[pt;pb;hst;hsb]; % all the 3D points
[k,v]=convhull(pAll); % wrap the points and compute volume
fprintf('Volume=%.3e\n',v)
Volume=1.323e-09
figure
trisurf(k,pAll(:,1),pAll(:,2),pAll(:,3),'FaceColor','c','EdgeColor','none')
axis equal; camlight
I am attaching a script which has the code above, with more comments and an additional plot.
  12 Commenti
Sam Chak
Sam Chak il 21 Ott 2025 alle 13:07
+1 👍 to you and @Matt J. Loved all three solutions as they are practical and well-explained. Initially, I was confused because I thought the OP wanted to estimate the air volume of a section of the circular ventilation duct with a 45° bend, rather than the elliptical duct.
William Rose
William Rose il 21 Ott 2025 alle 13:44
@Sam Chak, nice photo! THank you! Your comme nt means a lot, considering how many nice solutions and explanations you have posted.

Accedi per commentare.

Più risposte (2)

Matt J
Matt J il 17 Ott 2025 alle 8:39
Modificato: Matt J il 17 Ott 2025 alle 13:58
Along the lines of what @Mathieu NOE commented, I think it does make more sense to start with an elliptic cylinder and clip off the top and bottom with cutting planes. That will be much easier than approaching it as a solid of revolution:
%Volume parameters
N=1000;
ellipse=scale(nsidedpoly(N),[1.5,1]);
planeSlope=0.1;
planeHeight=0.2;
cylLength=0.5;
%Get the outside vertices
X=ellipse.Vertices(:,1);
Y=ellipse.Vertices(:,2);
Z=linspace(-cylLength,+cylLength,N);
[X,Z]=ndgrid(X,Z);
Y=repmat(Y,1,N);
keep=Z<=planeSlope*X+planeHeight & Z>=-planeSlope*X-planeHeight;
X=X(keep); Y=Y(keep); Z=Z(keep);
%Triangulate and compute volume
[K,volume]=convhulln([X,Y,Z]);
volume,
volume = 1.8849
%Display
trisurf(K, X, Y, Z, ...
'FaceColor', 'cyan', 'EdgeColor', 'none');
axis equal
camlight
view(-15,15)
  5 Commenti
Matt J
Matt J il 17 Ott 2025 alle 16:47
There are many videos explaing how a volume can be determined by revolving an area around an axis;
But when the area is changing with angle? That seems non-standard.
Matt J
Matt J il 17 Ott 2025 alle 17:02
Modificato: Matt J il 17 Ott 2025 alle 17:03
To make the movie, you could use this File Exchange tool,
which computes the intersection of two triangulated surfaces. To triangulate your solid you would give inputs from my code,
TR = triangulation(K,X,Y,Z);
while the second triangulated surface would just be the cut plane you want for a particular frame of your movie. You would represent the plane as a sufficiently big rectangle (two triangles) passing through S.

Accedi per commentare.


Matt J
Matt J il 17 Ott 2025 alle 23:54
Modificato: Matt J il 19 Ott 2025 alle 16:04
Here's a little bit more of a polished version of my original answer, which also generates a movie of the trapezoidal cross-sections. You can adjust the VideoWriter properties to your liking.
This code requires the download of AxelRot,
%Volume parameters (independent)
N=100; %discretize the perimeter into N points
diam=8; %tube diameter
ho=1;
hi=4;
xS=-3; %x-coordinate of S
%Volume parameters (derived)
dh=(hi-ho)/2;
angle=atand(dh/diam);
axMajor=hypot(diam,dh);
hS=ho+2*dh/diam*(xS+diam/2);
%Compute boundary vertices
t=linspace(0,360,N+1)'; t(end)=[];
V=0.5*[axMajor*cosd(t),diam*sind(t),0*t];
XYZ1=AxelRot( (V+[0,0,+ho/2])' ,+angle,[0,-1,0], [-diam/2,0,+ho/2])';
XYZ2=AxelRot( (V+[0,0,-ho/2])' ,-angle,[0,-1,0], [-diam/2,0,-ho/2])';
XYZ=[XYZ1;XYZ2];
%Triangulate and compute volume
[K,volume]=convhulln(XYZ);
volume,
volume = 122.1617
%Display
trisurf(K, XYZ(:,1), XYZ(:,2), XYZ(:,3), ...
'FaceColor', 'cyan', 'EdgeColor', 'none','FaceAlpha',0.5);
axis equal; xlabel x; ylabel y; zlabel z
camlight
view(-30,20)
%Movie
shg
v=VideoWriter('trapezoidMovie.mp4','MPEG-4');
v.Quality=95;
v.FrameRate=30;
v.open;
for i=1:N
A=XYZ1(i,:);
B=XYZ2(i,:);
C=[xS,0,-hS/2];
D=[xS,0,+hS/2];
args=num2cell([A;B;C;D;A],1);
[x,y,z]=deal(args{:});
h=line(x,y,z,Color='r',LineWidth=2);
drawnow;
v.writeVideo(getframe(gcf));
if i<N, delete(h); end
end
v.close
  24 Commenti
William Rose
William Rose il 20 Ott 2025 alle 0:25
Modificato: William Rose il 20 Ott 2025 alle 0:27
[Edit: add .mpeg file made by the script]
This script makes a series of figures similar to the nice ones by @John D'Errico, but the surrounding volume is the convex hull around all the trapezoids, instead of being a cylinder with an elliptical cross section, sliced by two planes. I realize that this convex hull is not perfect, as discussed in an earlier comment. But this convex hull is exactly correct along the non-planar top and bottom edges, which you can see by rotating it to az=0, el=0. Screenshots from the .mpeg file during playback are shown, at the 8th and final frames.
William Rose
William Rose il 20 Ott 2025 alle 1:51
Modificato: William Rose il 20 Ott 2025 alle 1:52
@Robert Demyanovich, you wrote:
"Are you now of the mind that your original equation for dV is correct? Or are you just using it as a point of reference."
I think my equation for dV is correct,
,
to the extent that each dV has the same length, p, on each long sides. This is a pretty good approximation, when the wedges are skinny. In my code, I use the length of the trailing edge of each wedge to calculate dV, all the way around. This means I overestimate the volume of each dV, for phi=0 to 180, because the leading edge is shorter than the trailing edge. But from phi=180 to 360, I underestimate the volume of each wedge, because the leading edge is longer than the trailing edge. The errors in my dVs from phi=0 to 180 pretty much cancel out the errors from 180 to 360, and that is why vol=sum(dV) does not change (at 4 significant digits), when I vary N from 40 wedges (9 deg each) to 720 (0.5 deg each).
If you need each dV to be more accurate, use p=mean(leading & trailing edge lengths) in the formula for each dV, instead of using p=trailing edge length.
For one wedge, comprised of 6 vertices, I expect the volume from convhull() will be very close to the volume from the formula, if we use the mean value of p. Check this with the following commands, after running rotateTrapezoid, with N=80:
wedge1verts=[hst;hsb;pt([1,2],:);pb([1,2],:)]; % array with 6 vertices of wedge 1
[~,wedge1vol]=convhull(wedge1verts); % wedge volume from convhull
p1=mean(p(1:2)); % mean p for wedge 1
dV1=(B*p1^3/3+hs*p1^2/6)*dt; % wedge volume from formula
fprintf('convhull volume=%.3e, formula volume=%.3e.\n',wedge1vol,dV1)
convhull volume=1.052e-10, formula volume=1.053e-10.
The two volume estimates are very close, as expected.

Accedi per commentare.

Tag

Community Treasure Hunt

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

Start Hunting!

Translated by