-
Notifications
You must be signed in to change notification settings - Fork 0
/
drawAsCylinder.m
92 lines (83 loc) · 3.26 KB
/
drawAsCylinder.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
function drawAsCylinder(fid, pp)
% drawAsCylinder(fid, pp)
%
% Approximate a patch or surface object as a cylinder (in the general
% sense, i.e. an object obtained by rotating a 2D curve around a rotation
% axis). Determine the relevant parameters (symmetry axis and shape) and
% write the resulting shape to file using the Povray scripting language.
%
% Input:
% - fid: File identifier
% - pp: graphics object (path or surface)
%
% Author: Sigurd Schelstraete, 2019
if isequal(pp.Type ,'surface')
vertices = unique([pp.XData(:) pp.YData(:) pp.ZData(:)], 'rows', 'stable');
elseif isequal(pp.Type ,'patch')
all_verts = pp.Faces(:);
all_verts(isnan(all_verts)) = [];
vertices = pp.Vertices(all_verts,:);
else
error('Object type not supported')
end
if isequal(pp.Parent.Type, 'hgtransform')
ht = pp.Parent;
vertices = vertices*ht.Matrix(1:3,:)';
end
if isfield(pp.('UserData'),'povray')
povray_options = pp.('UserData').('povray');
else
povray_options = struct();
end
if isequal(pp.FaceColor, 'flat') || isequal(pp.FaceColor, 'interp')
facecolor = NaN;
else
facecolor = pp.FaceColor;
end
% Fit data to cylinder
[rot_curve, centr_axis, center] = fit_cylinder(vertices);
Npts = size(rot_curve,1);
if Npts >=3
pfit = polyfit(rot_curve(:,1), rot_curve(:,2), 2);
else
pfit = polyfit(rot_curve(:,1), rot_curve(:,2), 1);
pfit = [0 pfit(:)'];
end
% Write povray code to generate the rotation object (cylinder, cone or lathe)
if norm(pfit(1:2))/norm(pfit(3)) < 1e-5 % constant -> cylinder
fprintf(fid,'cylinder {\n');
fprintf(fid,'\t<%10.6f, %10.6f, %10.6f>,\n', 0, rot_curve(1, 1), 0);
fprintf(fid,'\t<%10.6f, %10.6f, %10.6f>,\n', 0, rot_curve(end, 1), 0);
fprintf(fid,'\t%10.6f\n', mean(rot_curve(:,2)));
fprintf(fid,'\topen\n'); % TODO: determine whether open or closed
elseif norm(pfit(1))/norm(pfit(2:3)) < 1e-5 % linear -> cone
fprintf(fid,'cone {\n');
fprintf(fid,'\t<%10.6f, %10.6f, %10.6f>, %10.6f\n', 0, rot_curve(1, 1), 0, rot_curve(1, 2));
fprintf(fid,'\t<%10.6f, %10.6f, %10.6f>, %10.6f\n', 0, rot_curve(end, 1), 0, rot_curve(end, 2));
fprintf(fid,'\topen\n'); % TODO: determine whether open or closed
else % quadratic or more -> lathe
fprintf(fid,'lathe {\n');
fprintf(fid,'\tlinear_spline\n');
fprintf(fid,'\t%d,\n', Npts);
for i_r=1:Npts
fprintf(fid,'\t<%10.6f, %10.6f>', rot_curve(i_r, 2), rot_curve(i_r, 1));
if i_r ~= Npts
fprintf(fid,',');
end
fprintf(fid,'\n');
end
end
face_color = pp.FaceColor;
fprintf(fid,'\tpigment { color rgbt <%4.3f, %4.3f, %4.3f, %4.3f> }\n',face_color(1), face_color(2), face_color(3), 0);
rmat = alignVectors(centr_axis([1 3 2]), [0 1 0]);
fprintf(fid,'\t\tmatrix <%10.6f, %10.6f, %10.6f,\n', rmat(1,1), rmat(1,2), rmat(1,3));
fprintf(fid,'\t\t\t%10.6f, %10.6f, %10.6f,\n', rmat(2,1), rmat(2,2), rmat(2,3));
fprintf(fid,'\t\t\t%10.6f, %10.6f, %10.6f,\n', rmat(3,1), rmat(3,2), rmat(3,3));
fprintf(fid,'\t\t\t%10.6f, %10.6f, %10.6f>\n', center(1), center(3), center(2));
if isfield(povray_options, 'Texture')
fprintf(fid,'\ttexture { %s }\n', povray_options.Texture);
end
if isfield(povray_options, 'InteriorTexture')
fprintf(fid,'\tinterior_texture { %s }\n', povray_options.InteriorTexture);
end
fprintf(fid,'}\n');