Generates normals with multiple three-point coordinates
古いコメントを表示
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);
2 件のコメント
DGM
2025 年 9 月 27 日
Unless you're just doing this as an exercise in making an STL encoder for sake of whimsy (been there), none of this is necessary. Just write the FV data to an STL. The normals are calculated internally by the encoder.
% the model
F = [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];
V = [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];
% write the file to a binary STL
T = triangulation(F,V);
stlwrite(T,'test.stl')
That will write a compact, portable binary STL. Unless you want to read the triangulation to your children as a bedtime story, send it via teletype, or are trying to create a file which is compatible with a pre-1987 version of the slicer used with the prototype of the SLA-1, ASCII STL is just a waste of space (and often a silent degradation in precision). Otherwise, if unquestionably desired or absolutely necessary, you can just do:
% okay fine, write an ASCII STL instead
% this will be written with enough precision
% to losslessly represent float32 coordinates and normals
stlwrite(T,'test.stl','text')
Otherwise, if you just need to get the unit normals for some other reason, you can get them from the triangulation object:
% just get the face normals
N = faceNormal(T); % bam done.
The STL encoder is available in R2018b+. The use of triangulation.faceNormal is available in R2013a+, and similar functionality is available via the TriRep class back to R2009a.
William Rose
2025 年 9 月 29 日
@DGM, thanks for the info and the humor!
採用された回答
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で STL (STereoLithography) についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
