Set vector direction to point away from a closed surface (or a point coordinate)?
    5 visualizaciones (últimos 30 días)
  
       Mostrar comentarios más antiguos
    
Dear all,
I am plotting a closed potato-shaped surface using "patch", then adding some tangent planes using
plane=surf(x,y,z)
But when I am plotting the normals of those planes, using
normals=plane.FaceNormals
some of them are pointing "inwards" towards the potato, while others point outward away from it. How can I make them all point away from the surface (or the center) of the potato?
Thank you kindly!
0 comentarios
Respuestas (1)
  David Goodmanson
      
      
 el 19 de Dic. de 2017
        Hi LMS,
Say you set up a point B in the middle of the volume. Assuming the surface is not excessively curved, from B you should be able to reach every point on the skin with a straight line without leaving the potato. Suppose dface is the displacement vector from B to the middle of a face. The the dot product of dface with an outward face normal should be positive. The code below checks for that and and changes the sign of the face normal accordingly.
I'm assuming you have m x n matrices of the x,y and z coordinates. If you fed x and y vectors to surf, then you will have to use meshgrid to get the appropriate x and y matrices.
nvecs is a (m-1) x (n-1) x 3 matrix of the FaceNormal vectors, which you got in the way you described.
v = cat(3,x,y,z);         % construct vertices of faces
B = mean(mean(v));        % center, approximately
v =  v - B;               % translate to put center point at the origin
% find centers of faces
vcf = (1/4)*(v(1:end-1,1:end-1,:)+v(1:end-1,2:end,:) ...
           + v(  2:end,1:end-1,:)+v(  2:end,2:end,:));
sdot = sign(dot(vcf,nvecs,3))         % want these all to be positive
nvecs_new = nvecs.*repmat(sdot,1,1,3);
sdot = sign(dot(vcf,nvecs_new,3))     % check, all positive
I think the third line will have to be done with repmat if you don't have a fairly new version of Matlab.
You can eyeball a value for B, but it would have to be entered as B(1,1,:) = [bx by bz]
2 comentarios
  Esteban Garcia
 el 29 de Sept. de 2022
				Is there any other way ?, because my surface can be excessively curved...
Thank you
  Darrel Robertson
 el 10 de Jul. de 2024
				
      Editada: Darrel Robertson
 el 11 de Jul. de 2024
  
			- For highly concave objects (e.g. a torus or any object with holes or cavities in it) determine if your origin, O, is inside or outside the object (or intentionally pick an origin outside the object).
- Determine any point, P, on the face of interest
- Calculate the intersection of the line segment OP from O to P with every face and count how many faces OP passes through. Do not include the face in which P lies (if you do, then invert statement 4).
- If O is inside the object and you pass through an even number of faces (e.g. zero for a convex shape), then the vector OP is outward facing. Conversely if you pass through an odd number of faces then OP is inward facing. If O is outside the object then the opposite is true.
- Take the dot product of OP with the calculated normal. Positive means your normal is outward or inward the same as whatever OP is. Negative means the opposite.
- Invert the normal as desired (or vertex ordering of that face if using assumed clockwise or anticlockwise ordering)
- Repeat for every face/normal
https://www.mathworks.com/matlabcentral/fileexchange/169468-checkoutwardnormals
Ver también
Categorías
				Más información sobre Surface and Mesh Plots en Help Center y File Exchange.
			
	Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!



