V = 
how to create a volume from the revolution of a variable area trapezoid
Show older comments
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?


48 Comments
John D'Errico
on 17 Oct 2025
Edited: John D'Errico
on 17 Oct 2025
Sorry. I was going to write some code for surfaces of revolution a few years ago. Did not finish it, probably because I was not sure what I wanted the result to be, and what degree of flexibility it needed. Sadly, there are a lot of tools I've partly built over the years, so I have a moderately large bone yard of code, round tuits. :(
You can get what you want, (I think, if Im guessing right about what you want) by starting with a cylinder, then a simple linear transformation of it would give you the blue thingy.
Anyway, what result would you want to see? I.e., a triangulated surface? Just a pretty picture? Both? Something else?
Robert Demyanovich
on 17 Oct 2025
Edited: Robert Demyanovich
on 17 Oct 2025
Walter Roberson
on 17 Oct 2025
To insert latex, start in text mode anywhere on a line, and either at the beginning of a line or after a space, type a $ and then immediately the latex code, and finish by typing a $ again. The first thing after the initial $ must not be a space, and the last thing before the closing $ must not be a space. Upon typing the closing $ the latex will immediately be rendered.
If there is some problem with the latex entry or if you want to edit it, position your cursor immediately after the rendered latex, and press your backspace key . That will change the rendered version to plain text version again. To re-render, position immediately after the closing $ and press space.
Latex mode does not work in code blocks, or in "code example" blocks.
The supported latex in latex mode here exceeds that which is supported by MATLAB 'latex' interpreter, or which is supported by "insert equation" in Live Script. Unfortunately there does not appear to be documentation about what exactly is supported.
Robert Demyanovich
on 17 Oct 2025
Robert Demyanovich
on 17 Oct 2025
Matt J
on 17 Oct 2025
But
is not a function of ϕ? It is constant?
Robert Demyanovich
on 17 Oct 2025
Edited: Robert Demyanovich
on 17 Oct 2025
Robert Demyanovich
on 17 Oct 2025
Mathieu NOE
on 17 Oct 2025
maybe I'm reading the post a bit too fast , but if the goal is just to generate a plot, the blue section is basically just and elliptic tube that intersect two planes ... do we really need all this complicated maths ?
William Rose
on 17 Oct 2025
Edited: William Rose
on 17 Oct 2025
[Edit: fix typos in the text. Code and formulas are not changed.]
[Edit: add equation for, and calculation of, hs.]
Thank you for posting an interesting problem.
You say in your original post that you want to "create a volume by revolving a variable area trapezoid around the y axis". However, you say that Figure 1 (figure with an ellipse) in the original post shows the x-y plane. In that case, the +z axis points upward out of that plane of Figure 1, and goes through point S. Is that correct? (It would help if each 2D figure included labels for axes.) You say Fig. 2 in the original post shows the x-z plane, and you say that the axis of rotation passes vertically through point S in Figure 2. Therefore it seems the trapezoid revolves about the z axis. But that contradicts what you said earlier. Please clarify.
You write in the original post
It seems to me, based on your other explanations and comments, that the area given by the equaiton above is the area when
, because it is only when
that
. It seems to me that a more general formula for the area is
Am I understanding the problem correctly?
Your equation for p/R appears on my screen as a bunch of text that looks like it should be a Latex equation. So I will try to make it appear as a formatted equation:

And w, R, and θ are simply constants:
, R=0.0006, w=0.0007908. Then
and the equation above can be written
and the equation above can be written
(Check my math there: did I do that right?) Then we can plot of
versus ϕ, and we can plot
in the x,y plane:
phi=0:pi/20:2*pi; w=7.908e-4; R=6e-4;
% Compute p(phi):
p=((w/2)*cos(phi)+(R^2*(sin(phi).^2+0.5*cos(phi).^2)-(w^2/2)*sin(phi).^2).^0.5)./(sin(phi).^2+0.5*cos(phi).^2);
% Plot results
figure;
subplot(211), plot(phi,p,'-r.')
grid on; xlabel('\phi'); ylabel('p'); title('p(\phi)');
subplot(212), plot(p.*cos(phi),p.*sin(phi),'-r.');
grid on; xlabel('x'); ylabel('y'); title('p(x,y)')
The lower plot above looks consistent with the plot of p(x,y) in Fig.1 of your original post.
Your Figure 3 from the original post is below:
I am not sure why use you use subscripts h_i and h_k, above. I think hi=hk when the angle
is small, so it would make more sense to label both h's in the figure as
. You provide the following equation for the total volume:
We can infer from the equation above that you believe that the volume of the 3-dimensional wedge in the figure above is

I do not think that is correct. IF the thick end of the wedge were perpendicular to the wedge long axis (and it's not perpendicular), then the volume would be

where p is a function of ϕ, and therefore dV is a function of ϕ. That's what I think, but you should check my work.
The thick end of the wedge is not perpendicular to the long axis of the wedge, so the preceding formula needs a correction factor which equals unity when the end is perpendicular, and the correction factor is less than 1, but more than 0, otherwise. The end of the wedge is perpendicular to the long axis only when
and when
.
You say
and
. Then
. It follows from the equation I provided above for
that
. Therefore
.
To insert latex, start in text mode anywhere on a line, and either at the beginning of a line or after a space, type a $ and then immediately the latex code, and finish by typing a $ again.
Or enter latex in the formula editor,

This is good when you have multi-line formulas.
Robert Demyanovich
on 17 Oct 2025
Edited: Robert Demyanovich
on 17 Oct 2025
Robert Demyanovich
on 17 Oct 2025
William Rose
on 17 Oct 2025
Edited: William Rose
on 17 Oct 2025
@Robert Demyanovich, thank you for checking my work.
[Edit: run the code so that it generates a figure. Change my conclusion: Robert D is right, no adjustment is needed.]
I now recognize that you are right and I was thinking incorrectly. As you said earlier, there is no need for an adjustment factor for the differential volume, dV.
The figure below shows a view of the object from above, i.e. a slice through the object in the x-y plane, through z=0. Three triangles are highlighted to show that the edge of the triangle that is opposite point S is generally not perpendicular to the long axis of the triangle. But no adjustment to the volume formula is needed, because the width of the triangle, perpendicular to the long axis, is p(t)*dt.
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]'-dt/2; % 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);
px=p.*cos(t); py=p.*sin(t);
figure
plot(px,py,'--k'); hold on
plot([0;px(1:2);0],[0;py(1:2);0],'-r')
plot([0;px(6:7);0],[0;py(6:7);0],'-g')
plot([0;px(11:12);0],[0;py(11:12);0],'-b')
xlabel('x'); ylabel('y')
text(0,-4e-5,'S')
grid on; axis equal
Robert Demyanovich
on 17 Oct 2025
William Rose
on 17 Oct 2025
@Robert Demyanovich, there was no figure because I forgot to run my code before posting the comment. I have fixed that now, and I have adjusted my conclusion - see edited comment above.
Paul
on 20 Oct 2025
I'm confused about the volume integral that's shown above, which is
(unless that's changed in the comments below). I'm trying to relate that back to a simpler 2D case to express the area enclosed by p(phi), which I guess would be the area of solid in the z=0 plane. It seems like the area integral analagous to that volume integral would be
but that wouldn't be correct, would it? It's missing a factor of two, i.e., the correct area integral in polar coordinates is
Similarly, would the volume integral have to account for the change in height going from h(phi) to h(phi + dphi) (I'm not sure about this).
Robert Demyanovich
on 20 Oct 2025
Does the proposed volume integral work for simple case?
For example, instead of variable area trapezoid, let's use a constant area trapezoid. And let's use a simple trapezoid, e.g., a rectangle.
Let hs = 1, h(phi) = 1, and p(phi) =2, so that our trapezoid is really a rectangle with area h*phi = 2. The solid of revolution is a cylinder, and the volume of that cylinder is pi*r^2*h = 4*pi.
syms f(x) g(x)
f(x) = 0.5; g(x) = -0.5;
V = 2*sym(pi)*int(x*abs(f(x)-g(x)),x,0,2)
Using the formula above, we have
syms A(phi) p(phi)
A(phi) = 2; p(phi) = 2;
V = int(A(phi)*phi,phi,0,2*sym(pi))
Robert Demyanovich
on 20 Oct 2025
Edited: Robert Demyanovich
on 20 Oct 2025
Robert Demyanovich
on 20 Oct 2025
Edited: Robert Demyanovich
on 20 Oct 2025
William Rose
on 20 Oct 2025
What you are proposing is what we already did. That is the integral I solved to get the formula which I posted many comments ago:


The next step is to solve the integral
where

I don't know how to solve that integral, and neither does Wolfram Alpha. I tried.
Therefore you solve it numerically. My code already does this, by two methods, which give the same answers, as shown in one of my other comments. Method 1 (called method 2 in my other comment) is to compute each dV using the formula for dV, above. Method 2 (called method 3 in my other comment) is to compute dV as the volume of the convex hull around the six vertices of the wedge dV. (Method 1, in the other comment, is the tetrahedralization approach. @Matt J says it also gives the same answer, when an earlier typo is fixed.)
Robert Demyanovich
on 20 Oct 2025
William Rose
on 20 Oct 2025
@Robert Demyanovich, you're welcome.
Robert Demyanovich
on 22 Oct 2025
Edited: Robert Demyanovich
on 22 Oct 2025
The blue area doesn't show us the height of any single one of the wedges. It's the height of the projection of the entire volume on the x-z plane.
The concavity of an object is not preserved under perspective projection. Think of a bowl-shaped solid. In 3D, it is concave, but its projection is convex.
Robert Demyanovich
on 22 Oct 2025
Matt J
on 22 Oct 2025
Depends how far away the camera is. If you stood at the foot of the Seattle Space Needle, you wouldn't be able to see the tip of the needle, even though it is the highest point. The observation deck would be in the way.
Robert Demyanovich
on 22 Oct 2025
Edited: Robert Demyanovich
on 22 Oct 2025
So, which heights at other azimuthal angles could be larger than the height at d$\phi$ = 0,
All of them, depending again on where the camera is positioned. Even though those parts of the object have a lower height in 3D, they become bigger from the camera's perspective if they are closer to the camera, while the parts farther away get smaller. The bottom line is, we need to know where you put the camera.
doesn't matter where I am located on the z plane
Not sure what the "z-plane" is. Do you mean you've translated the camera up and down in z, but kept it at the same (x,y) coordinates? This might be a good time to mention that we haven't seen the code that generated these perspectives. It limits our ability to assess the rendering precisely.
Robert Demyanovich
on 22 Oct 2025
Robert Demyanovich
on 22 Oct 2025
It looks like William Rose commented on this issue several days ago
You haven't provided a link to his comment, but you might be refering to this comment, describing that the top surface of your volume is not planar. An implication of this is that the central spine of your volume (at
) is in fact not the highest. For every fixed x, the points at the rim of your volume are higher than at the center.
That does indeed explain what you are seeing, but I still wanted to illustrate how, even when the top surface is planar, you can still see the concave envelope, depending on your display settings. In this first figure below, I plot the cutoff cylinder that I showed you how to generate using AxelRot. The top and bottom surfaces are planes perpendicular to the x-z plane, and therefore the central spine of the object really is maximally high in this case for any fixed x.
figure;
plotVolume();
view(-30,20)
Accordingly at view(0,0), the central trapezoid is snug against the blue envelope of the object, as long as the axes' Projection property is orthographic (the default).
figure;
plotVolume();
view(0,0)
However, if we switch to perspective projection, which is how peoples' eyes more naturally see the world, the central trapezoid will never be flush with the upper an lower envelopes of view(0,0), and you get the concave envelope. This is because the edge closer to the observer will always appear higher than the central spine.
figure;
plotVolume();
view(0,0)
set(gca,'Projection','perspective');
function plotVolume()
%Volume parameters (independent)
N=100; %discretize the perimeter into N points
diam=6; %tube diameter
ho=1;
hi=4;
xS=-2; %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];
%Display
trisurf(convhulln(XYZ), XYZ(:,1), XYZ(:,2), XYZ(:,3), ...
'FaceColor', 'cyan', 'EdgeColor', 'none','FaceAlpha',0.3);
axis equal; xlabel x; ylabel y; zlabel z
camlight
%Movie
i=1;
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{:});
line(x,y,z,Color='r',LineWidth=2);
view(0,0)
camdolly(0,+30,0,'fixtarget','data');
end
Robert Demyanovich
on 23 Oct 2025
William Rose
on 24 Oct 2025
Robert Demyanovich
on 24 Oct 2025
Edited: Robert Demyanovich
on 24 Oct 2025
the matlab code tends to overestimate a bit over the majority of possible values of θ.
Makes sense. The top surface seems to be convex over most of its area, so you would expect the wedge elements to provide an outer bound on the sections of the volume they approximate.
Robert Demyanovich
on 24 Oct 2025
Edited: Robert Demyanovich
on 24 Oct 2025
Were you talking to me? I don't think I have a volume computation approach of my own anymore that is distinctive from one of @William Rose's. As far as I am aware there are only two volume computation methods that are finalists, and they are as below, from this comment.
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)
The one I would have the most confidence in is the computation of wedge1vol using convhull.
As for his analytical wedge volume formula,
dV1=(B*p1^3/3+hs*p1^2/6)*dt;
I sort of get it, but I have the impression that p1=mean(p(1:2)) is being used as a surrogate for the altitude of the triangular base of the wedge. That might be a legit approximation, but I don't immediately see what guarantees it.
Robert Demyanovich
on 24 Oct 2025
Well most of that is invalid now, because it was assuming the object was convex. We determined later that the real object you're working with is not convex, and that the volume had to be computed piece-wise, by dividing the object into incremental wedges.
Robert Demyanovich
on 24 Oct 2025
Based on what I posted for your code, the difference seems very large (7.6E-10 from your code versus 1.29E-09 from the integral equation)
I don't know what you did to arrive at that, but below is my idea of an apples-to-apples comparison. You can see that using my original computation (convexVolume) is about 5% greater than the trueVolume (computed using wedges). That seems consistent with the plot, which visualizes of how much convhulln overestimates the volume of the object. The blue region is the convex hull (the object boundary as interpreted by convhulln). The parts of the red trapezoids that are hidden from view (they sort of go underwater into the blue area) are where the true boundaries of the object go strictly inside the hull.
N=60; % 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
trueVolume=0;
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.')
k=[i,i+1];
if i==N, k=[N,1]; end
wedgeVerts=[hst;hsb;pt(k,:);pb(k,:)]; % array with 6 vertices of wedge 1
[~,dV]=convhull(wedgeVerts); % wedge volume from convhull
trueVolume=trueVolume+dV;
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');
axis equal; grid on; view(-45,25)
%Display
V=[pt;pb;hst;hsb];
[K,convexVolume]=convhulln(V);
convexVolume,
trueVolume
trisurf(K, V(:,1), V(:,2), V(:,3), ...
'FaceColor', 'cyan', 'EdgeColor', 'none','FaceAlpha',1);
axis equal; xlabel x; ylabel y; zlabel z
camlight
view(-30,20)
hold off
Robert Demyanovich
on 25 Oct 2025
Edited: Robert Demyanovich
on 25 Oct 2025
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)
Inner integral
I = int(1,z,0,z_u)
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)
Middle integral
I = int(r*I,r,0,p(phi))
Define h(phi) and substitute, bring in the factor of 2
syms B
h(phi) = B*p(phi);
I = expand(2*subs(I))
Hence the volume is
V = int(I,phi,0,2*sym(pi))
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 = isolate(eqn,p)
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)
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'})
William Rose
on 25 Oct 2025
I didn't see any solutions using integral3 (apologies if this has already been done in code attachments, I didn't look at those), which eliminates the need to explicitly define dV.
theta = pi/4;
R = 0.0006;
B = 0.8670;
w = 0.0007908;
p = @(phi) (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)*R;
h = @(phi) B*p(phi);
h_s = h(pi/2);
z_u = @(phi,r) h_s/2 + (h(phi)/2 - h_s/2)./p(phi).*r;
I = @(phi,r,z) 2*r;
V = integral3(I,0,2*pi,0,p,0,z_u)
Accepted Answer
More Answers (2)
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,
%Display
trisurf(K, X, Y, Z, ...
'FaceColor', 'cyan', 'EdgeColor', 'none');
axis equal
camlight
view(-15,15)
5 Comments
Robert Demyanovich
on 17 Oct 2025
Edited: Robert Demyanovich
on 17 Oct 2025
Can MatLab also measure the volume of the solid produced by rotating the trapezoid around the z axis (i.e. by not requiring the volume equation shown in my original post)?
That is what my code has already done (in numerical approximation), assuming you agree that the solid I have graphed matches what you are looking for.
As for the rest of what you are trying to do, I still think you are barking up the wrong tree by analyzing this as a solid of revolution, including your analytical volume computation. The volume can be decomposed into 3 parts: a central elliptic cylinder section, whose volume is trivially
and two identical upper and lower sections with triangular x-z profiles (see below). The upper and lower sections should be fairly easy triple integrals in Cartesian coordinates. Note from symmetry that you really only need to integrate over one half (illustrated below) of one section
%keep=Z<=planeSlope*X+planeHeight & Z>=planeSlope*min(X)+planeHeight & Y>=0;
Robert Demyanovich
on 17 Oct 2025
Edited: Robert Demyanovich
on 17 Oct 2025
Matt J
on 17 Oct 2025
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.
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.
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,
%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 Comments
Robert Demyanovich
on 18 Oct 2025
Matt J
on 18 Oct 2025
which is what I think you are supposed to do with Matlab script (version 2021).
No, you were meant to leave AxelRot in its own file, just as you downloaded it. You need to put the file in a folder that is on your Matlab path, and then you can call it from anywhere.
Matt J
on 18 Oct 2025
I've modified the example to include an export of the movie frames to an .mp4 video file.
Robert Demyanovich
on 18 Oct 2025
I don't know what you did. What are the folder paths where you have put AxelRot.m and the other code? Did you look at your Matlab search path to see that those folders are on it? Does executing this at the command line give you anything?
which AxelRot
If all else fails, putting all code files that you want to use in the current Matlab folder is enough for Matlab to see everything.
Robert Demyanovich
on 19 Oct 2025
Robert Demyanovich
on 19 Oct 2025
Edited: Robert Demyanovich
on 19 Oct 2025
I though it would be on the line
Yes, that sets the playback speed for the video file (not the speed at which Matlab updates the figure). If you want Matlab to loop more slowly, you can stick a pause command at the bottom of the loop.
I thought it would be by default in the Folder that contains the codes, but it isn't there.
It should be.
Sorry, it may be because you are writing to a JPEG 2000 video. The settings should have been,
v=VideoWriter('trapezoidMovie.mp4','MPEG-4');
v.Quality=95;
Robert Demyanovich
on 19 Oct 2025
Robert Demyanovich
on 19 Oct 2025
Edited: Robert Demyanovich
on 19 Oct 2025
You can't accept two, but don't worry. Just accept one and up-vote the other.
To improve video quality, use a maximized figure window when recording the video, and increase the LineWidth, e.g.,
h=line(x,y,z,Color='r',LineWidth=3);
There are programmatic ways to maximize the figure window, but it might be easiest if you just do it manually.
Robert Demyanovich
on 19 Oct 2025
William Rose
on 19 Oct 2025
I'm curious: do you have the same video quality issue with the code I posted? I realize it makes a different movie.
Regarding speed of rotation in @Matt J's code: His code saves one angular step per frame. So you can increase N in his code: then it will take a smaller angular step each time. Or you can decrease v.FrameRate from the usual 30 (fps) to something slower. Adding a pause statement will make is slower when you run the code and see it in Matlab, but it will not change how the video plays back, because the video is always 1 angular step per frame.
Robert Demyanovich
on 19 Oct 2025
Edited: Robert Demyanovich
on 19 Oct 2025
The equations that I presented indicate that to the rear of the stagnation point (S), the height does not seem to indicate a linear change (if viewed in the x-z plane).
So, the volume we are talking about is no longer meant to have a purely trapezoidal cross-section in the x-z plane, like you had here?

I don't see how the change can be "nonlinear" in the x-z plane to the rear of S, if every cut through S is supposed to be a trapezoid.
As for the video generation, I don't see anything in my video-generation code that wasn't also in @William Rose's.
Robert Demyanovich
on 19 Oct 2025
William Rose
on 19 Oct 2025
Edited: William Rose
on 19 Oct 2025
[Edit: add a screenshot which I meant to include earlier.]
I see what you mean about the shape in the x-z plane. When I use the 3D rotate tool to rotate the 3D figure that my code makes, to view it looking down the y axis (az=0, el=0), I get this view:

This view makes clear something I had not realized, but which you obviously did realize: the "top" and "bottom" sides of the volume swept out by the trapezoid are not planes.
Non-planarity of the top and bottom also explains the persistent difference of about 5% between the volume of the convex hull and the volume obtained as the sum of the skinny slices. I should have realized this before. The figure below shows the trapezoids at 0, 45, and -45 degrees of rotation. The view is almost exactly down the y- axis, but not quite, because if it were exactly down the y-axis, the +45 and -45 trapezoids would exactly overlap. Notice how the top and bottom edges of the 0 degree trapezoid below the edges of the +,-45 degree trapezoids, in this view. That means the top surface dips down slightly, i.e. it is concave.

If you play around with the wireframe diagram, rotating with your mouse or touchpad in 3D, you can also appreciate the concave nature of the top and bottom surfaces. Here's a screenshot - but its easier to see the concavity when it's moving around, so try it on your machine, if you're skeptical.

The script I used to draw the overall wire frame and the convex hull and the figure with three trapezoids is attached: rotateTrapezoid.m. It does not save a video file.
Since the shape is concave in places, convhull() overestimates the volume. It also means that the volume obtained by taking planar slices through the top and bottom of the elliptical cylinder is not exactly the volume swept out by the rotating trapezoid.
I don't think that my equation forces a view in the x-z plane to show a linear reduction in the top and bottom planes.
It does if that view is cross-sectional. Since the solid is created by revolving trapezoids, then the x-z plane cross section through the solid must be comprised of two trapezoids stitched together, one at
and one at
. I acknowledge that the two trapezoids do not have to combine to form a single larger trapezoid, but they must combine to form something that is at least piecewise linear.
Robert Demyanovich
on 19 Oct 2025
Edited: Robert Demyanovich
on 19 Oct 2025
Robert Demyanovich
on 19 Oct 2025
Edited: Robert Demyanovich
on 19 Oct 2025
Robert Demyanovich
on 20 Oct 2025
William Rose
on 20 Oct 2025
Edited: William Rose
on 20 Oct 2025
[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
on 20 Oct 2025
Edited: William Rose
on 20 Oct 2025
@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.
Categories
Find more on Multibody Dynamics 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!

























