]> Creatis software - CreaPhase.git/blob - octave_packages/geometry-1.5.0/io/@svg/normalize.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / geometry-1.5.0 / io / @svg / normalize.m
1 %% Copyright (c) 2011 Juan Pablo Carbajal <carbajal@ifi.uzh.ch>
2 %%
3 %%    This program is free software: you can redistribute it and/or modify
4 %%    it under the terms of the GNU General Public License as published by
5 %%    the Free Software Foundation, either version 3 of the License, or
6 %%    any later version.
7 %%
8 %%    This program is distributed in the hope that it will be useful,
9 %%    but WITHOUT ANY WARRANTY; without even the implied warranty of
10 %%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 %%    GNU General Public License for more details.
12 %%
13 %%    You should have received a copy of the GNU General Public License
14 %%    along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16 %% -*- texinfo -*-
17 %% @deftypefn {Function File} @var{SVGn} = normalize (@var{SVG})
18 %% normalizes and SVG.
19 %% @end deftypefn
20
21 function [SVGn bb] = normalize (obj)
22
23   SVGn = obj;
24   bb = [];
25   if ! obj.Data.normalized
26
27     ids = fieldnames (obj.Path);
28     npath = numel(ids);
29     v = zeros(npath,2);
30     bb = zeros(1,4);
31
32     for ip = 1:npath
33       v(ip,:) = shapecentroid(obj.Path.(ids{ip}).data);
34       p = shape2polygon(obj.Path.(ids{ip}).data);
35       bb = mergeBoxes(bb, [min(p) max(p)]([1 3 2 4]));
36     end
37
38     if npath > 1
39       v = mean(v)(:);
40     else
41       v = v.';
42     end
43
44     %% check whether document and bounding box agree.
45     bbHeight = bb(2)-bb(1);
46     bbWidth = bb(4)-bb(2);
47
48     if obj.Data.height != bbHeight
49       warning("svg:normalize:Sanitycheck",...
50       ["Height of SVG %g and height boundingbox %g don't match.\n" ...
51        "Using bounding box.\n"],obj.Data.height,bbHeight)
52     end
53
54     if obj.Data.width != bbWidth
55       warning("svg:normalize:Sanitycheck",...
56       ["Width of SVG %g and width boundingbox %g don't match.\n" ...
57       "Using bounding box.\n"],obj.Data.width,bbWidth)
58     end
59
60     %% Move paths such that center of SVG is at 0,0
61     %% Put coordinates in the usual frame
62     %% Scale such that diagonal of bounding box is 1
63     Dnorm = sqrt (bbWidth ^ 2 + bbHeight ^ 2);
64     S = (1 / Dnorm) * eye (2);
65     bb = zeros(1,4);
66
67     for ip = 1:npath
68       SVGn.Path.(ids{ip}).data = shapetransform(obj.Path.(ids{ip}).data,-v);
69
70       % Put to middle
71       SVGn.Path.(ids{ip}).data = ...
72                         shapetransform(SVGn.Path.(ids{ip}).data,[0; -bbHeight/2]);
73       % Reflect y
74       SVGn.Path.(ids{ip}).data = ...
75                              shapetransform(SVGn.Path.(ids{ip}).data,[1 0;0 -1]);
76       % Put to bottom
77       SVGn.Path.(ids{ip}).data = ...
78                         shapetransform(SVGn.Path.(ids{ip}).data,[0; bbHeight/2]);
79
80       % Scale
81       SVGn.Path.(ids{ip}).data = ...
82                         shapetransform(SVGn.Path.(ids{ip}).data,S);
83
84       p = shape2polygon(SVGn.Path.(ids{ip}).data);
85       bb = mergeBoxes(bb, [min(p) max(p)]([1 3 2 4]));
86     end
87     bbHeight = bb(2)-bb(1);
88     bbWidth = bb(4)-bb(2);
89
90     SVGn.Data.height = bbHeight;
91     SVGn.Data.width = bbWidth;
92     SVGn.Data.normalized = true;
93   end
94
95 end