Generates normals with multiple three-point coordinates

2 ビュー (過去 30 日間)
Chenglin Li
Chenglin Li 2023 年 2 月 25 日
コメント済み: William Rose 2023 年 2 月 25 日
Hi!,I wanted to generate multiple three-dimensional coordinate normals in matlab and output them in fixed format to generate stl files, but I kept making mistakes. I want to know why, and I hope you can help me.
Nodes = [0 0 0;
4 0 0;
4 4 0;
0 4 0
4 0 2;
0 0 2;
4 1 2;
0 1 2;
0 1 1;
4 1 1;
4 2 1;
4 2 2;
0 2 2;
0 2 1;
0 4 2;
4 4 2];
singletriangle = [5 10 7;
5 2 10;
10 2 3;
3 11 10;
3 16 11;
16 12 11;
6 8 9;
6 1 9;
9 1 4;
9 4 14;
14 4 15;
14 15 13];
% Find the point coordinates according to the triangle index
points_triangles = [Nodes(singletriangle,1),Nodes(singletriangle,2),Nodes(singletriangle,3)];
% Find the point coordinates of each column (three-dimensional)
points_one=points_triangles(1:length(points_triangles)/3,:);
points_two=points_triangles(length(points_triangles)/3+1:length(points_triangles)/3*2,:);
points_three=points_triangles(length(points_triangles)/3*2+1:length(points_triangles),:);
% Subtract the matrix and compute the vector
vectors_one=points_two-points_one;
vectors_two=points_three-points_one;
% Take the cross product of two vectors
normal_vectors=cross(vectors_one,vectors_two);
% Normalizes the 3D vector so that its modulus is equal to 1
normalized_normal_vectors=normal_vectors./norm(normal_vectors);
% Initializes the empty array
output=zeros(length(points_one)*4,3);
% Write output data
for i=1:length(points_one)
output(i*4-3,:)=normalized_normal_vectors(i,:);
output(i*4-2,:)=points_one(i,:);
output(i*4-1,:)=points_two(i,:);
output(i*4,:)=points_three(i,:);
end
% Output content
output=output';
STL_file_name=['lin123','.stl'] ;
STL_file = fopen (STL_file_name,'wt');
fprintf (STL_file,'solid %s\n','solid');
fprintf (STL_file, ' facet normal %14e %14e %14e\n outer loop\n vertex %14e %14e %14e\n vertex %14e %14e %14e\n vertex %14e %14e %14e\n endloop\n endfacet\n',output);
fprintf (STL_file,'endsolid %s\n','solid' );
fclose (STL_file);

採用された回答

William Rose
William Rose 2023 年 2 月 25 日
編集済み: William Rose 2023 年 2 月 25 日
[edit: I simplified the calculation of the normalized normal vectors]
I ran your code. It runs without error. It makes an STL file (attached). I can render the STL file at https://www.viewstl.com without getting an error. What is the problem?
The rendered object looks like two 2-D sheets, rather than a 3-D object. I don;t know what you expect your object to look like. I recommend that you start with a simple set of points. I re-ran your code with 4 points and 4 triangles, to make a tetrahedron. It works. The STL file produces a tetrahedron when viewed at https://www.viewstl.com.
Nodes = [0 0 0;
1 0 0;
0 1 0;
0 0 1];
singletriangle = [1 3 2;
1 2 4;
1 4 3;
2 3 4];
% Find the point coordinates according to the triangle index
points_triangles = [Nodes(singletriangle,1),Nodes(singletriangle,2),Nodes(singletriangle,3)];
% Find the point coordinates of each column (three-dimensional)
points_one=points_triangles(1:length(points_triangles)/3,:);
points_two=points_triangles(length(points_triangles)/3+1:length(points_triangles)/3*2,:);
points_three=points_triangles(length(points_triangles)/3*2+1:length(points_triangles),:);
% Subtract the matrix and compute the vector
vectors_one=points_two-points_one;
vectors_two=points_three-points_one;
% Take the cross product of two vectors
normal_vectors=cross(vectors_one,vectors_two);
% Normalizes the 3D vector so that its modulus is equal to 1
normalized_normal_vectors=normal_vectors./norm(normal_vectors);
% Initializes the empty array
output=zeros(length(points_one)*4,3);
% Write output data
for i=1:length(points_one)
output(i*4-3,:)=normalized_normal_vectors(i,:);
output(i*4-2,:)=points_one(i,:);
output(i*4-1,:)=points_two(i,:);
output(i*4,:)=points_three(i,:);
end
% Output content
output=output';
STL_file_name=['tetra.stl'] ;
STL_file = fopen (STL_file_name,'wt');
fprintf (STL_file,'solid %s\n','solid');
fprintf (STL_file, ' facet normal %14e %14e %14e\n outer loop\n vertex %14e %14e %14e\n vertex %14e %14e %14e\n vertex %14e %14e %14e\n endloop\n endfacet\n',output);
fprintf (STL_file,'endsolid %s\n','solid' );
fclose (STL_file);
The code above makes a tetrahedron. Maybe you are not happy with the normal vectors. Let us inspect them:
disp(normal_vectors)
0 0 -1 0 -1 0 -1 0 0 1 1 1
These normal vectors point in the expected directions: outward from each face.
However, the normalized normal vectors do not have unit length:
disp(normalized_normal_vectors)
0 0 -0.5000 0 -0.5000 0 -0.5000 0 0 0.5000 0.5000 0.5000
That is a problem. Modify the normalization command. You did
normalized_normal_vectors=normal_vectors./norm(normal_vectors);
That does not give the desired result, because norm(X) returns a scalar when X is a matrix. Use vecnorm() instead:
nnv=normal_vectors./(vecnorm(normal_vectors'))';
disp(nnv)
0 0 -1.0000 0 -1.0000 0 -1.0000 0 0 0.5774 0.5774 0.5774
nnv looks like the correct set of normal vectors with unit length.
Good luck.

その他の回答 (1 件)

Chenglin Li
Chenglin Li 2023 年 2 月 25 日
Thank you very much. I wanted to generate a concave surface before, but the figure was not what I wanted. After your program test, I found that it reached my expected effect, which helped me a lot, thank you!!!

カテゴリ

Help Center および File ExchangeSTL (STereoLithography) についてさらに検索

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by