Prev: GUI design
Next: Matlab and FTDI VCP drivers
From: Walter Roberson on 21 Mar 2010 18:11 Chris McGibbon wrote: > I was thinking in much simpler terms (the sphere I need is more like a > disco ball), but yes, I can see why it would advantageous to have > normals at vertices for more complex surfaces. So I guess if I'm going > to give Matlab the VertexNormal matrix, I would have to first compute > the suface normals, and then from surface normals that associate with > each vertex, compute an "average" normal? Ummm, I don't know how to efficiently calculate a vertex normal. If you set the other properties, then Matlab will calculate the VertexNormal matrix itself. You would only provide the VertexNormal matrix if you wish to override the way that Matlab lights the surface. You mentioned in an earlier posting that normally the normal of a flat surface would be calculated by taking the cross product of the direction vector of any two edges of the patch. That leads me to ponder what the mathematical result would be of taking the cross product of the direction vectors of all of the edges connected to a vertex? My linear algebra is quite rusty so I'm blanking on what to expect from such a calculation.
From: Chris McGibbon on 21 Mar 2010 18:25 Walter Roberson <roberson(a)hushmail.com> wrote in message <ho61ab$6rs$1(a)canopus.cc.umanitoba.ca>... > Chris McGibbon wrote: > > > A surface normal is usually found by taking the cross-product of the > > direction vectors of any two edges of the patch (surface) -- this will > > give you the direction that the face points for lighting purposes. I > > still don't understand why Matlab calculates vertex normals instead -- > > they are 1-D points and techincally do not have normals! > > Hmmm? Vertices are only 1-D points if you are working with line segments > in a single dimension. When you have a patch object, the vertices are > all 2D (plus an implicit 0 for Z) or 3D. > > Suppose you have a complex curved surface and you wish to find the > normal to it at a given point. Then you start by examining the gradient > in one direction, and you refine by examining the gradient in another > direction... but you do not have the "true" normal until you have > examined the gradient in all directions. To phrase that another way, the > "true" normal is a limit over all possible (infinite number of) > directions of a calculation involving the gradients in each direction. > If the surface is generated by a polynomial then by looking at the order > of the polynomial you can calculate the number of basis vectors you will > need to use to find the true normal; likewise, if the surface is > generated by an infinite function (e.g, e^x) that gives "nice" results > when a series expansion of it is calculated, *possibly* you could prove > convergence without evaluating the gradients along an infinite number of > basis vectors. Unfortunately, some surfaces are just not tractable to > being approximated by polynomials, so for them, to calculate the normal, > you have to truncate somewhere and hope that you can express the error > bounds and that the error bounds are not highly non-linear... > > Thus it seems to me that it *is* meaningful to calculate the normal of a > vertex given the directions of the connected edges -- meaningful as a > truncation of the infinite expansion of adding more and more connected > edges as the approximation to the curved surface is refined. I was thinking in much simpler terms (the sphere I need is more like a disco ball), but yes, I can see why it would advantageous to have normals at vertices for more complex surfaces. So I guess if I'm going to give Matlab the VertexNormal matrix, I would have to first compute the suface normals, and then from surface normals that associate with each vertex, compute an "average" normal?
From: Jan Simon on 21 Mar 2010 18:42 Dear Chris! > I'm trying to create a 3D sphere using patch ('Vertices' and 'Faces' method), that reflects light from a light object. Have you seen this function from Andres: http://www.mathworks.com/matlabcentral/fileexchange/23882-surfo Good luck, Jan
From: Chris McGibbon on 22 Mar 2010 02:05 "Jan Simon" <matlab.THIS_YEAR(a)nMINUSsimon.de> wrote in message <ho67br$fel$1(a)fred.mathworks.com>... > Dear Chris! > > I'm trying to create a 3D sphere using patch ('Vertices' and 'Faces' method), that reflects light from a light object. > > Have you seen this function from Andres: > http://www.mathworks.com/matlabcentral/fileexchange/23882-surfo > > Good luck, Jan Thanks, it sounded positive and I gave it a try. When using facenorm to recompute the VertexNormals, none of my patches show lighting. Here's the code I'm using (including call to facenorm). It's not terribly sophisticated but it should be able to draw a lighted sphere. ----------------------------------------------------------------------- % Program to draw a sphere and paint the quadrants alternating colors % Construct the sphere coordinates. Order of vertices has 1st point at % north pole (z=1) and last point at south pole (z=-1). Points in between % fall on latitude circles and go counter-clockwise around the sphere from % north to south pole. ph = [60,30,0,-30,-60]*pi/180; np = length(ph); % Elevation angles th = [0:11]*30*pi/180; nt = length(th); % Azimuth angles nc = np*nt+2; % Number of vertices xyz = zeros(3,nc); for i=1:np % First compute all the points in between the poles for j=1:nt xyz(1,1+j+nt*(i-1)) = cos(ph(i)).*cos(th(j)); xyz(2,1+j+nt*(i-1)) = cos(ph(i)).*sin(th(j)); xyz(3,1+j+nt*(i-1)) = sin(ph(i)); end end xyz(1:3,1)=[0.0,0.0,1.0]; % Then add the pole coordinates. xyz(1:3,nc)=[0.0,0.0,-1.0]; % Use facenorm.m to recompute vertex normals Vnorm = zeros(nc,3); Vnorm(:,:) = facenorm(xyz(1,:),xyz(2,:),xyz(3,:)); Q = zeros(4,9,8); % Initialize a matrix to hold face indices % Quadrant I Q(1,:,1) = [1,1,1,2,3,4,14,15,16]; Q(2,:,1) = [2,3,4,14,15,16,26,27,28]; Q(3,:,1) = [3,4,5,15,16,17,27,28,29]; Q(4,:,1) = [NaN,NaN,NaN,3,4,5,15,16,17]; % Quadrant II Q(1,:,2) = [1,1,1,5,6,7,17,18,19]; Q(2,:,2) = [5,6,7,17,18,19,29,30,31]; Q(3,:,2) = [6,7,8,18,19,20,30,31,32]; Q(4,:,2) = [NaN,NaN,NaN,6,7,8,18,19,20]; % Quadrant III Q(1,:,3) = [1,1,1,8,9,10,20,21,22]; Q(2,:,3) = [8,9,10,20,21,22,32,33,34]; Q(3,:,3) = [9,10,11,21,22,23,33,34,35]; Q(4,:,3) = [NaN,NaN,NaN,9,10,11,21,22,23]; % Quadrant IV Q(1,:,4) = [1,1,1,11,12,13,23,24,25]; Q(2,:,4) = [11,12,13,23,24,25,35,36,37]; Q(3,:,4) = [12,13,2,24,25,14,36,37,26]; Q(4,:,4) = [NaN,NaN,NaN,12,13,2,24,25,14]; % Quadrant V Q(1,:,5) = [26,27,28,38,39,40,50,51,52]; Q(2,:,5) = [38,39,40,50,51,52,62,62,62]; Q(3,:,5) = [39,40,41,51,52,53,51,52,53]; Q(4,:,5) = [27,28,29,39,40,41,NaN,NaN,NaN]; % Quadrant VI Q(1,:,6) = [29,30,31,41,42,43,53,54,55]; Q(2,:,6) = [41,42,43,53,54,55,62,62,62]; Q(3,:,6) = [42,43,44,54,55,56,54,55,56]; Q(4,:,6) = [30,31,32,42,43,44,NaN,NaN,NaN]; % Quadrant VII Q(1,:,7) = [32,33,34,44,45,46,56,57,58]; Q(2,:,7) = [44,45,46,56,57,58,62,62,62]; Q(3,:,7) = [45,46,47,57,58,59,57,58,59]; Q(4,:,7) = [33,34,35,45,46,47,NaN,NaN,NaN]; % Quadrant VIII Q(1,:,8) = [35,36,37,47,48,49,59,60,61]; Q(2,:,8) = [47,48,49,59,60,61,62,62,62]; Q(3,:,8) = [48,49,38,60,61,50,60,61,50]; Q(4,:,8) = [36,37,26,48,49,38,NaN,NaN,NaN]; c = zeros(3,8); c(:,1) = [0 0 1]; c(:,3) = [0 0 1]; c(:,6) = [0 0 1]; c(:,8) = [0 0 1]; c(:,2) = [1 1 0]; c(:,4) = [1 1 0]; c(:,5) = [1 1 0]; c(:,7) = [1 1 0]; axes set(gca,'Projection','perspective'); axis vis3d axis equal axis off light('Position',[3,3,3],'Style','infinite'); lighting flat set(gcf,'Renderer','OpenGL') %camlight headlight % another lighting option I tried view(0,0); for i = 1:8 patch('Vertices',xyz','Faces',Q(:,:,i)',... 'FaceColor',c(:,i),'EdgeColor',c(:,i),'FaceVertexCData',c(:,i),... 'FaceLighting','gouraud','EdgeLighting','gouraud',... 'AmbientStrength',0.6,'EraseMode','normal',... 'BackFaceLighting','reverselit','LineStyle','none',... 'VertexNormals',Vnorm); end
From: Jan Simon on 22 Mar 2010 08:48
Dear Chris! > for i = 1:8 > patch('Vertices',xyz','Faces',Q(:,:,i)',... > 'FaceColor',c(:,i),'EdgeColor',c(:,i),'FaceVertexCData',c(:,i),... > 'FaceLighting','gouraud','EdgeLighting','gouraud',... > 'AmbientStrength',0.6,'EraseMode','normal',... > 'BackFaceLighting','reverselit','LineStyle','none',... > 'VertexNormals',Vnorm); > end As far as I can see, your VNorm consists of NaN's only. Most likely you call facenorm with the wrong input. And are you sure that you want to apply the same Vnorm to all 8 PATCH objects?! Kind regards, Jan |