Prev: GUI design
Next: Matlab and FTDI VCP drivers
From: Chris McGibbon on 21 Mar 2010 15:41 I'm trying to create a 3D sphere using patch ('Vertices' and 'Faces' method), that reflects light from a light object. All works well except for one very annoying, and perplexing, problem. While most patch surfaces reflect light corrrectly (outside surface only), for others -- only their inside surface reflects light, and the outside remains unaffected by the light. When creating the 'faces' matrix I have listed my vertex indices in consistent counterclockwise direction -- I assumed this was how Matlab determined which side to light-up... but apparenty not. I set the 'BackLighting' property to 'reverselit' as that seems to work best, but the other options give worse results. When I look at the surface normal data that Matlab generates (and stores in the VertexNormal property) its size is the number of vertices and not the number of surfaces... How can a vertex have a normal? It is a point. Can someone explain to me how Matlab determines which side a patch to light?
From: Walter Roberson on 21 Mar 2010 16:02 Chris McGibbon wrote: > When I look at the surface normal data that Matlab generates (and stores > in the VertexNormal property) its size is the number of vertices and not > the number of surfaces... How can a vertex have a normal? It is a point. Speaking in generalities, which might be completely different than how Matlab actually does things: In geometry and calculus, tangents (and thus normals) are *always* at a point, and reflect the direction that the nearby points are to the point in question. You can then see how this could be extended to a vertex by calculating the vectors towards each of the connected vertices instead of going through a full differentiation (of a formula you don't even have) to calculate the slopes of connected points in "all directions". You could possibly find a normal by minimizing the sum of squares of the 2D angles between a proposed normal and the vectors towards each of the connected vertices (though you might need a hint to know which side is "outside"). But there's probably a much simpler way to calculate it!
From: Chris McGibbon on 21 Mar 2010 16:22 Walter Roberson <roberson(a)hushmail.com> wrote in message <ho5u01$1to$1(a)canopus.cc.umanitoba.ca>... > Chris McGibbon wrote: > > > When I look at the surface normal data that Matlab generates (and stores > > in the VertexNormal property) its size is the number of vertices and not > > the number of surfaces... How can a vertex have a normal? It is a point. > > Speaking in generalities, which might be completely different than how > Matlab actually does things: > > In geometry and calculus, tangents (and thus normals) are *always* at a > point, and reflect the direction that the nearby points are to the point > in question. You can then see how this could be extended to a vertex by > calculating the vectors towards each of the connected vertices instead > of going through a full differentiation (of a formula you don't even > have) to calculate the slopes of connected points in "all directions". > > You could possibly find a normal by minimizing the sum of squares of the > 2D angles between a proposed normal and the vectors towards each of the > connected vertices (though you might need a hint to know which side is > "outside"). But there's probably a much simpler way to calculate it! 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! Anyway, the work around was to use camlight('headlight') instead of a default light source - that seemed to solve the lighting problem.
From: Walter Roberson on 21 Mar 2010 16:58 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.
From: Chris McGibbon on 21 Mar 2010 17:49
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? |