RGL plot : lighting problem when triangle3d and persp3d are used in the same plot
On 28/08/2012 7:49 AM, Stephane Chantepie wrote:
thanks for the reply I am sorry but I do not have any skills in C++ Nevertheless, I found a solution to my problem... By using another package "misc3d" and more precisely the association of the two functions drawScene.rgl and surfaceTriangles drawScene.rgl(surfaceTriangles(x,y,z,color="gray",smooth=1)) The idea behind this trick is to transform the matrix in triangle surfaces before to plot them. I hope this could help someone else
Thanks, I didn't know about those functions. Duncan Murdoch
cheers 2012/8/27 Duncan Murdoch <murdoch.duncan at gmail.com>
On 27/08/2012 1:47 PM, Stephane Chantepie wrote:
Dear all, I have tried to plot a triangular matrix with the function persp3d(rgl). for example z=rbind(c(1,NA,NA,NA),c(5,3,**NA,NA),c(4,2,9,NA),c(8,6,5,11)**) x=1:4 y=1:4 persp3d(x,y,z,color="gray") The two extreme points are not plotted (value=1 and value=10). It seems because the half of the matrix have 'NA' and perp3d need planar quadrilateral face. So I decided to use the function triangle3d to integrate these points into the scene. So, for the first point I did : triangles3d(x=c(1,2,2),y=c(1,**1,2),z=c(1,5,3)) and it worked But a problem remains because the light movment on this triangle looks independant and I did not find how to solve this issue. How can I prefectly integrate this triangle into the scene?
You need to set the normals at the vertices that are shared with the persp3d vertices. rgl internally averages the normals to the pieces making up each facet; you don't have enough access to the internals to do that. (You'd want to change the normal on the surface, as well, because your triangles should participate in the averaging.) But you could set the normals to the new triangle to match the normal to the one it joins to, and get something that looks sort of okay. It's not going to be a simple calculation: you need to figure out the coordinates of the edges joining at those vertices, take a cross product, and use that. See ?rgl.primitive for how to send the normals to points3d; I think the normals need to be length 1, but that may be forced internally. If you were really ambitious, you could take a look at the C++ code that draws the surface, and contribute code to smooth the edge properly; I think it would be an improvement over the current behaviour, but it is tedious to write. Duncan Murdoch