I’m making a function which generalizes the cylinder function so that the cylinder has caps, can be any size and orientation. However on the look of the cylinder I am running into a jam. To get the caps to look right the curved part needs one set of shading and the caps need another. (And before you ask making 3 surfaces is not an option)
Here is the relevant code:
surface(xSurf,ySurf,zSurf,c,'EdgeColor','none','FaceLighting','phong');
and in case you want to see the whole code.
Thank you for your help,
John
function varargout = DrawCylinder(x,y,z,r,h,aVec,bVec,cVec,ccolor, npts)
% DrawCylinder Generate a three-dimensional cylinder
%
% DrawCylinder(x,y,z,a,b,c,aVec,bVec,CVec,ccolor, npts)
% creates a surface plot of a cylinder whose center is at (x,y,z), has
% semiaxes of length a, b, and c. The unit vectors associated with each
% semixis are aVec, bVec, and cVec and must be size 3 x 1 (column vector)
% with size of npts + 1.
%
% H = DrawCylinder(...) creates the surface plot and returns the handle H to each
% graphical object created.
%
% [X Y Z] = DrawCylinder(...) does not generate the surface plot and returns
% the data necessary to create the surface using:
% SURF(X,Y,Z);
%
% [X Y Z C] = DrawCylinder(...) does not generate the surface plot and returns
% the data necessary to create the surface using:
% SURF(X,Y,Z,C,'cdataMapping','direct');
%CREATE SURFACE FOR CYLINDER
[xCyl,yCyl,zCyl]=cylinder(1,npts);
xSurf=[zeros(1,max(size(xCyl)));xCyl;zeros(1,max(size(xCyl)))];
ySurf=[zeros(1,max(size(yCyl)));yCyl;zeros(1,max(size(yCyl)))];
zSurf=[zeros(1,max(size(zCyl)));zCyl;ones(1,max(size(zCyl)))] - 0.5;
xSurf = xSurf*r;
ySurf = ySurf*r;
zSurf = zSurf*h;
%ROTATE CYLINDER
%Make sure aVec,bVec, and cVec are column unit vectors:
if all(size(aVec)==[1,3])
aVec=aVec';
end
if all(size(bVec)==[1,3])
bVec=bVec';
end
if all(size(cVec)==[1,3])
cVec=cVec';
end
aVec=aVec/norm(aVec); %Make unit vectors
bVec=bVec/norm(bVec);
cVec=cVec/norm(cVec);
rot = [aVec,bVec,cVec]; %The rotation matrix
[iMax, jMax] = size(xSurf);
for i=1:iMax
for j=1:jMax
rotatedPt = rot*[xSurf(i,j);ySurf(i,j);zSurf(i,j)];
xSurf(i,j) = rotatedPt(1);
ySurf(i,j) = rotatedPt(2);
zSurf(i,j) = rotatedPt(3);
end
end
%TRANSLATE CYLINDER
xSurf = xSurf + x;
ySurf = ySurf + y;
zSurf = zSurf + z;
c = ccolor*ones(size(xSurf));
if nargout == 0
surface(xSurf,ySurf,zSurf,c,'EdgeColor','none','FaceLighting','phong');
elseif nargout == 1
varargout = {surface(xSurf,ySurf,zSurf,c,'EdgeColor','none','FaceLighting','phong');};
elseif nargout == 3
varargout = {xSurf ySurf zSurf};
elseif nargout == 4
varargout = {xSurf ySurf zSurf c};
end
end
Edit 8/18/12:
Just so you can see.
This is what I am getting …

And this is what I want …

I’m pretty sure that by “shade” you simply mean the colors of the end caps and not a more complicated effect. If so that’s pretty straightforward, I’ll give an example in gray scale
Change
to
the first line initializes the
cmatrix with a normalized ccolor (expecting an 8 bit greyscale ccolor input, it normalizes to 0..1). The second line changes the caps (rows 1 and 3) to be a slightly darker color bottoming out at 0 and leaves the cylinder surfaces (rows 2 and 4) alone.In order to make sure you see the results correctly, you need to alter the nargout==0 condition so that it looks like this
The colormap just sets the colormap, similar to an 8 bit gray scale. The caxis command is fairly critical. According to Matlab’s surface documentation
For our purposes that is bad. Since we only have two values the lowest would be changed to 0 and the highest to 1. That effectively ignores our ccolor input and gives a white cylinder with two black caps. Using
caxis([0 1])preserves the full scale and ccolor’s position within it.Update:
Sounds like I misunderstood what you wanted, the easiest way to achieve something very close to the effect you want is to set ‘MeshStyle’ to ‘row’, like this:
surface(xSurf,ySurf,zSurf,c,’EdgeColor’,’k’,’FaceLighting’,’phong’,’MeshStyle’,’row’);
This will give you the following result :
There’s still a central point, but it’s by far the simplest way to produce that effect.