Matlab:设置单个曲面的阴影

3

我正在制作一个函数,它可以将圆柱体功能泛化,使其具有盖子,可以是任何大小和方向。然而,在圆柱体的外观上,我遇到了一些问题。为了使盖子看起来正确,曲线部分需要一组阴影,而盖子需要另一组阴影。(在你问之前,制作3个表面不是一个选项)

以下是相关代码:

    surface(xSurf,ySurf,zSurf,c,'EdgeColor','none','FaceLighting','phong');

如果你想查看整个代码,请参考以下内容。

感谢您的帮助,

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

编辑于8/18/12:

只是为了让您看到。

这就是我得到的...

这就是我得到的

而这就是我想要的...

而这就是我想要的

1个回答

1
我相信你所说的“shade”只是指端盖的颜色,而不是更复杂的效果。如果是这样的话,那就很简单了,我会给出一个灰度示例。
更改
c = ccolor*ones(size(xSurf));

c = (ccolor/255)*ones(size(xSurf));
c([1 3],:)=max(0,(ccolor-10))/255;

第一行使用标准化的颜色(期望8位灰度颜色输入,将其标准化为0..1)初始化 c 矩阵。第二行将帽子(第1行和第3行)更改为稍微较暗的颜色,底部为0,并保留圆柱体表面(第2行和第4行)。

为了确保您正确地看到结果,您需要修改nargout == 0条件,使其看起来像这样

surface(xSurf,ySurf,zSurf,c,'EdgeColor','none','FaceLighting','phong');
colormap(gray(256));
caxis([0 1]);

调色板只是设置调色板,类似于8位灰度。caxis命令非常关键。根据Matlab的表面文档

MATLAB对这些数据执行线性变换以从当前调色板中获取颜色

对于我们的目的来说,这是不好的。由于我们只有两个值,最低值将被更改为0,最高值将被更改为1。这有效地忽略了我们的ccolor输入,并给出了一个带有两个黑色盖子的白色圆柱体。使用caxis([0 1])保留了完整的比例尺和ccolor在其中的位置。

更新:

听起来我误解了你想要的东西,实现非常接近你想要的效果的最简单方法是将'MeshStyle'设置为'row',像这样:

surface(xSurf,ySurf,zSurf,c,'EdgeColor','k','FaceLighting','phong','MeshStyle','row');

这将给您以下结果:capped_cylinder

仍然有一个中心点,但这绝对是产生该效果的最简单方法。


对于圆形的'EdgeColor',我需要在面部和圆形部分上使用'none',并在圆周周围使用[0 0 0]。此外,'FaceLighting'在面部为'flat',在圆形部分为'phong'。 - user1543042

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接