1 %% Copyright (C) 2004-2012 David Legland <david.legland@grignon.inra.fr>
2 %% All rights reserved.
4 %% Redistribution and use in source and binary forms, with or without
5 %% modification, are permitted provided that the following conditions are met:
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.
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.
24 %% 2012 Adapted to Octave by Juan Pablo Carbajal <carbajal@ifi.uzh.ch>
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
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.
44 %% DRAWGRAPH(NODES, EDGES, FACES)
45 %% also draw faces of the graph as patches.
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
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'.
64 %% return handle to the set of edges.
66 %% [HN, HE] = DRAWGRAPH(...)
67 %% return handle to the set of nodes and to the set of edges.
69 %% [HN, HE, HF] = DRAWGRAPH(...)
70 %% Also return handle to the set of faces.
73 function varargout = drawGraph(varargin)
77 % uses empty arrays by default for edges and faces
81 % default styles for nodes, edges, and faces
83 % nodes are drawn as red circles
84 sn = {'linestyle', 'none', 'color', 'r', 'marker', 'o'};
86 % edges are drawn as blue lines
87 se = {'linestyle', '-', 'color', 'b'};
89 % faces are cyan, their edges are not drawn
90 sf = {'EdgeColor', 'none', 'Facecolor', 'c'};
93 %% Process input arguments
95 % case of a call without arguments
101 % ---------------------------------------------------------------
102 % First extract the graph structure
106 % graph is stored as a cell array: first cell is nodes, second one is
107 % edges, and third is faces
117 % graph is stored as a structure, with fields 'nodes', 'edges', and
118 % eventually 'faces'.
121 if isfield(var, 'faces')
126 % graph is stored as set of variables: nodes, edges, and eventually
132 if ~isempty(varargin)
135 % faces are stored in a numeric array of indices
140 % faces are stored in a cell array, each cell containing a
141 % row vector of indices
149 % extract drawing style
151 if ~isempty(varargin)
152 sn = concatArguments(sn, varargin{1});
155 if length(varargin)>1
156 se = concatArguments(se, varargin{2});
159 if length(varargin)>2
160 sf = concatArguments(sf, varargin{3});
165 %% main drawing processing
170 % Draw a 2 dimensional graph ----------------------
172 % Draw faces of the graph ------------
173 if ~strcmp(sf{1}, 'none') && ~isempty(f)
175 % each face is contained in a cell.
178 hf(fi) = patch('Faces', f{fi}, 'Vertices', n, sf{:});
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{:});
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{:});
192 % Draw 2D nodes ----------------------
193 if ~strcmp(sn{1}, 'none')
194 hn = plot(n(:,1), n(:,2), sn{:});
199 % Draw a 3 dimensional graph ----------------------
201 % use a zbuffer to avoid display pbms.
202 set(gcf, 'renderer', 'zbuffer');
204 % Draw 3D Faces ----------------------
205 if ~strcmp(sf{1}, 'none')
207 % each face is contained in a cell.
210 hf(fi) = patch('Faces', f{fi}, 'Vertices', n, sf{:});
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{:});
219 % Draw 3D edges ----------------------
220 if ~strcmp(se{1}, 'none') && size(e, 1)>0
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)]', ...
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)]', ...
233 % Draw 3D nodes ----------------------
234 if ~strcmp(sn{1}, 'none');
235 hn = plot3(n(:,1), n(:,2), n(:,3), sn{:});
241 %% Format output arguments
243 % return handle to edges
248 % return handle to nodes and edges
254 % return handle to nodes, edges and faces
265 function res = concatArguments(in1, in2)
266 % in1 is a cell array already initialized
267 % in2 is an argument that can be:
269 % - the string 'none'
270 % - another cell array
278 if strcmp('none', in2)
285 res = [in1(:)' in2(:)'];
287 res = [{in1} in2(:)];