]> Creatis software - CreaPhase.git/blob - octave_packages/geometry-1.5.0/graphs/drawGraph.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / geometry-1.5.0 / graphs / drawGraph.m
1 %% Copyright (C) 2004-2012 David Legland <david.legland@grignon.inra.fr>
2 %% All rights reserved.
3 %%
4 %% Redistribution and use in source and binary forms, with or without
5 %% modification, are permitted provided that the following conditions are met:
6 %%
7 %%     1 Redistributions of source code must retain the above copyright notice,
8 %%       this list of conditions and the following disclaimer.
9 %%     2 Redistributions in binary form must reproduce the above copyright
10 %%       notice, this list of conditions and the following disclaimer in the
11 %%       documentation and/or other materials provided with the distribution.
12 %%
13 %% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS''
14 %% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 %% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 %% ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
17 %% ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 %% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 %% SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 %% CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21 %% OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 %% OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 %%
24 %% 2012 Adapted to Octave by Juan Pablo Carbajal <carbajal@ifi.uzh.ch>
25
26 %% -*- texinfo -*-
27 %% @deftypefn {Function File}  drawGraph (@var{nodes}, @var{edges})
28 %% @deftypefnx {Function File}  drawGraph (@var{nodes}, @var{edges}, @var{faces})
29 %% @deftypefnx {Function File}  drawGraph (@var{graph})
30 %% @deftypefnx {Function File}  drawGraph (@dots{}, @var{snodes})
31 %% @deftypefnx {Function File}  drawGraph (@dots{}, @var{snodes}, @var{sedges})
32 %% @deftypefnx {Function File}  drawGraph (@dots{}, @var{snodes}, @var{sedges}, @var{sfaces})
33 %% @deftypefnx {Function File}  {@var{h} = } drawGraph (@dots{})
34 %% @deftypefnx {Function File}  {[@var{h} @var{he}] = } drawGraph (@dots{})
35 %% @deftypefnx {Function File}  {[@var{h} @var{he} @var{hf}] = } drawGraph (@dots{})
36 %% Draw a graph, given as a set of vertices and edges
37 %%
38 %%   DRAWGRAPH(NODES, EDGES)
39 %%   draw a graph specified by a set of nodes (array N*2 or N*3,
40 %%   corresponding to coordinate of each node), and a set of edges (an array
41 %%   Ne*2, containing for each edge the first and the second node).
42 %%   Default drawing is a red circle for nodes and a blue line for edges.
43 %%
44 %%   DRAWGRAPH(NODES, EDGES, FACES)
45 %%   also draw faces of the graph as patches.
46 %%
47 %%   DRAWGRAPH(GRAPH)
48 %%   passes argument in a srtucture with at least 2 fields named 'nodes' and
49 %%   'edges', and possibly one field 'faces', corresponding to previously
50 %%   described parameters.
51 %%   GRAPH can also be a cell array, whose first element is node array,
52 %%   second element is edges array, and third element, if present, is faces
53 %%   array.
54 %%
55 %%
56 %%   DRAWGRAPH(..., SNODES)
57 %%   DRAWGRAPH(..., SNODES, SEDGES)
58 %%   DRAWGRAPH(..., SNODES, SEDGES, SFACES)
59 %%   specify the draw mode for each element, as in the classical 'plot'
60 %%   function. To not display some elements, uses 'none'.
61 %%
62 %%
63 %%   H = DRAWGRAPH(...)
64 %%   return handle to the set of edges.
65 %%
66 %%   [HN, HE] = DRAWGRAPH(...)
67 %%   return handle to the set of nodes and to the set of edges.
68 %%
69 %%   [HN, HE, HF] = DRAWGRAPH(...)
70 %%   Also return handle to the set of faces.
71 %%
72 %% @end deftypefn
73 function varargout = drawGraph(varargin)
74
75   %% initialisations
76
77   % uses empty arrays by default for edges and faces
78   e = [];
79   f = [];
80
81   % default styles for nodes, edges, and faces
82
83   % nodes are drawn as red circles
84   sn = {'linestyle', 'none', 'color', 'r', 'marker', 'o'};
85
86   % edges are drawn as blue lines
87   se = {'linestyle', '-', 'color', 'b'};
88
89   % faces are cyan, their edges are not drawn
90   sf = {'EdgeColor', 'none', 'Facecolor', 'c'};
91
92
93   %% Process input arguments
94
95   % case of a call without arguments
96   if nargin==0
97       help drawGraph;
98       return;
99   end
100
101   % ---------------------------------------------------------------
102   % First extract the graph structure
103
104   var = varargin{1};
105   if iscell(var)
106       % graph is stored as a cell array: first cell is nodes, second one is
107       % edges, and third is faces
108       n = var{1};
109       if length(var)>1
110           e = var{2};
111       end
112       if length(var)>2
113           f = var{3};
114       end
115       varargin(1) = [];
116   elseif isstruct(var)
117       % graph is stored as a structure, with fields 'nodes', 'edges', and
118       % eventually 'faces'.
119       n = var.nodes;
120       e = var.edges;
121       if isfield(var, 'faces')
122           f = var.faces;
123       end
124       varargin(1) = [];
125   else
126       % graph is stored as set of variables: nodes, edges, and eventually
127       % faces
128       n = varargin{1};
129       e = varargin{2};
130       varargin(1:2) = [];
131
132       if ~isempty(varargin)
133           var = varargin{1};
134           if isnumeric(var)
135               % faces are stored in a numeric array of indices
136               f = var;
137               varargin(1) = [];
138           elseif iscell(var)
139               if ~ischar(var{1})
140                   % faces are stored in a cell array, each cell containing a
141                   % row vector of indices
142                   f = var;
143                   varargin(1) = [];
144               end
145           end
146       end
147   end
148
149   % extract drawing style
150
151   if ~isempty(varargin)
152       sn = concatArguments(sn, varargin{1});
153   end
154
155   if length(varargin)>1
156       se = concatArguments(se, varargin{2});
157   end
158
159   if length(varargin)>2
160       sf = concatArguments(sf, varargin{3});
161   end
162
163
164
165   %% main drawing processing
166
167   hold on;
168
169   if size(n, 2)==2
170       % Draw a 2 dimensional graph ----------------------
171
172       % Draw faces of the graph ------------
173       if ~strcmp(sf{1}, 'none') && ~isempty(f)
174           if iscell(f)
175               % each face is contained in a cell.
176               hf = zeros(size(f));
177               for fi=1:length(f)
178                   hf(fi) = patch('Faces', f{fi}, 'Vertices', n, sf{:});
179               end
180           else
181               % process faces as an Nf*N array. Nf is the number of faces,
182               % and all faces have the same number of vertices (nodes).
183               hf = patch('Faces', f, 'Vertices', n, sf{:});
184           end
185       end
186
187       % Draw 2D Edges ----------------------
188       if ~strcmp(se{1}, 'none') && size(e, 1)>0
189           he = plot([n(e(:,1),1) n(e(:,2),1)]', [n(e(:,1),2) n(e(:,2),2)]', se{:});
190       end
191
192       % Draw 2D nodes ----------------------
193       if ~strcmp(sn{1}, 'none')
194           hn = plot(n(:,1), n(:,2), sn{:});
195       end
196
197
198   elseif size(n, 2)==3
199       % Draw a 3 dimensional graph ----------------------
200
201       % use a zbuffer to avoid display pbms.
202       set(gcf, 'renderer', 'zbuffer');
203
204       % Draw 3D Faces ----------------------
205       if ~strcmp(sf{1}, 'none')
206           if iscell(f)
207               % each face is contained in a cell.
208               hf = zeros(size(f));
209               for fi=1:length(f)
210                   hf(fi) = patch('Faces', f{fi}, 'Vertices', n, sf{:});
211               end
212           else
213               % process faces as an Nf*N array. Nf i the number of faces,
214               % and all faces have the same number of vertices (nodes).
215               hf = patch('Faces', f, 'Vertices', n, sf{:});
216           end
217       end
218
219       % Draw 3D edges ----------------------
220       if ~strcmp(se{1}, 'none') && size(e, 1)>0
221   %         he = plot3(...
222   %             [n(e(:,1),1) n(e(:,2),1)]', ...
223   %             [n(e(:,1),2) n(e(:,2),2)]', ...
224   %             [n(e(:,1),3) n(e(:,2),3)]', ...
225   %             se{:});
226           he = line(...
227               [n(e(:,1),1) n(e(:,2),1)]', ...
228               [n(e(:,1),2) n(e(:,2),2)]', ...
229               [n(e(:,1),3) n(e(:,2),3)]', ...
230               se{:});
231       end
232
233       % Draw 3D nodes ----------------------
234       if ~strcmp(sn{1}, 'none');
235           hn = plot3(n(:,1), n(:,2), n(:,3), sn{:});
236       end
237
238   end
239
240
241   %% Format output arguments
242
243   % return handle to edges
244   if nargout==1
245       varargout{1} = he;
246   end
247
248   % return handle to nodes and edges
249   if nargout==2
250       varargout{1} = hn;
251       varargout{2} = he;
252   end
253
254   % return handle to nodes, edges and faces
255   if nargout==3
256       varargout{1} = hn;
257       varargout{2} = he;
258       varargout{3} = hf;
259   end
260
261
262
263 endfunction
264
265 function res = concatArguments(in1, in2)
266   % in1 is a cell array already initialized
267   % in2 is an argument that can be:
268   %   - empty
269   %   - the string 'none'
270   %   - another cell array
271
272   if isempty(in2)
273       res = in1;
274       return;
275   end
276
277   if ischar(in2)
278       if strcmp('none', in2)
279           res = {'none'};
280           return;
281       end
282   end
283
284   if iscell(in1)
285       res = [in1(:)' in2(:)'];
286   else
287       res = [{in1} in2(:)];
288   end
289
290 endfunction