]> Creatis software - CreaPhase.git/blobdiff - 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
diff --git a/octave_packages/geometry-1.5.0/graphs/drawGraph.m b/octave_packages/geometry-1.5.0/graphs/drawGraph.m
new file mode 100644 (file)
index 0000000..490ef4c
--- /dev/null
@@ -0,0 +1,290 @@
+%% Copyright (C) 2004-2012 David Legland <david.legland@grignon.inra.fr>
+%% All rights reserved.
+%%
+%% Redistribution and use in source and binary forms, with or without
+%% modification, are permitted provided that the following conditions are met:
+%%
+%%     1 Redistributions of source code must retain the above copyright notice,
+%%       this list of conditions and the following disclaimer.
+%%     2 Redistributions in binary form must reproduce the above copyright
+%%       notice, this list of conditions and the following disclaimer in the
+%%       documentation and/or other materials provided with the distribution.
+%%
+%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS''
+%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+%% ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+%% ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+%% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+%% SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+%% CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+%% OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+%% OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+%%
+%% 2012 Adapted to Octave by Juan Pablo Carbajal <carbajal@ifi.uzh.ch>
+
+%% -*- texinfo -*-
+%% @deftypefn {Function File}  drawGraph (@var{nodes}, @var{edges})
+%% @deftypefnx {Function File}  drawGraph (@var{nodes}, @var{edges}, @var{faces})
+%% @deftypefnx {Function File}  drawGraph (@var{graph})
+%% @deftypefnx {Function File}  drawGraph (@dots{}, @var{snodes})
+%% @deftypefnx {Function File}  drawGraph (@dots{}, @var{snodes}, @var{sedges})
+%% @deftypefnx {Function File}  drawGraph (@dots{}, @var{snodes}, @var{sedges}, @var{sfaces})
+%% @deftypefnx {Function File}  {@var{h} = } drawGraph (@dots{})
+%% @deftypefnx {Function File}  {[@var{h} @var{he}] = } drawGraph (@dots{})
+%% @deftypefnx {Function File}  {[@var{h} @var{he} @var{hf}] = } drawGraph (@dots{})
+%% Draw a graph, given as a set of vertices and edges
+%%
+%%   DRAWGRAPH(NODES, EDGES)
+%%   draw a graph specified by a set of nodes (array N*2 or N*3,
+%%   corresponding to coordinate of each node), and a set of edges (an array
+%%   Ne*2, containing for each edge the first and the second node).
+%%   Default drawing is a red circle for nodes and a blue line for edges.
+%%
+%%   DRAWGRAPH(NODES, EDGES, FACES)
+%%   also draw faces of the graph as patches.
+%%
+%%   DRAWGRAPH(GRAPH)
+%%   passes argument in a srtucture with at least 2 fields named 'nodes' and
+%%   'edges', and possibly one field 'faces', corresponding to previously
+%%   described parameters.
+%%   GRAPH can also be a cell array, whose first element is node array,
+%%   second element is edges array, and third element, if present, is faces
+%%   array.
+%%
+%%
+%%   DRAWGRAPH(..., SNODES)
+%%   DRAWGRAPH(..., SNODES, SEDGES)
+%%   DRAWGRAPH(..., SNODES, SEDGES, SFACES)
+%%   specify the draw mode for each element, as in the classical 'plot'
+%%   function. To not display some elements, uses 'none'.
+%%
+%%
+%%   H = DRAWGRAPH(...)
+%%   return handle to the set of edges.
+%%
+%%   [HN, HE] = DRAWGRAPH(...)
+%%   return handle to the set of nodes and to the set of edges.
+%%
+%%   [HN, HE, HF] = DRAWGRAPH(...)
+%%   Also return handle to the set of faces.
+%%
+%% @end deftypefn
+function varargout = drawGraph(varargin)
+
+  %% initialisations
+
+  % uses empty arrays by default for edges and faces
+  e = [];
+  f = [];
+
+  % default styles for nodes, edges, and faces
+
+  % nodes are drawn as red circles
+  sn = {'linestyle', 'none', 'color', 'r', 'marker', 'o'};
+
+  % edges are drawn as blue lines
+  se = {'linestyle', '-', 'color', 'b'};
+
+  % faces are cyan, their edges are not drawn
+  sf = {'EdgeColor', 'none', 'Facecolor', 'c'};
+
+
+  %% Process input arguments
+
+  % case of a call without arguments
+  if nargin==0
+      help drawGraph;
+      return;
+  end
+
+  % ---------------------------------------------------------------
+  % First extract the graph structure
+
+  var = varargin{1};
+  if iscell(var)
+      % graph is stored as a cell array: first cell is nodes, second one is
+      % edges, and third is faces
+      n = var{1};
+      if length(var)>1
+          e = var{2};
+      end
+      if length(var)>2
+          f = var{3};
+      end
+      varargin(1) = [];
+  elseif isstruct(var)
+      % graph is stored as a structure, with fields 'nodes', 'edges', and
+      % eventually 'faces'.
+      n = var.nodes;
+      e = var.edges;
+      if isfield(var, 'faces')
+          f = var.faces;
+      end
+      varargin(1) = [];
+  else
+      % graph is stored as set of variables: nodes, edges, and eventually
+      % faces
+      n = varargin{1};
+      e = varargin{2};
+      varargin(1:2) = [];
+
+      if ~isempty(varargin)
+          var = varargin{1};
+          if isnumeric(var)
+              % faces are stored in a numeric array of indices
+              f = var;
+              varargin(1) = [];
+          elseif iscell(var)
+              if ~ischar(var{1})
+                  % faces are stored in a cell array, each cell containing a
+                  % row vector of indices
+                  f = var;
+                  varargin(1) = [];
+              end
+          end
+      end
+  end
+
+  % extract drawing style
+
+  if ~isempty(varargin)
+      sn = concatArguments(sn, varargin{1});
+  end
+
+  if length(varargin)>1
+      se = concatArguments(se, varargin{2});
+  end
+
+  if length(varargin)>2
+      sf = concatArguments(sf, varargin{3});
+  end
+
+
+
+  %% main drawing processing
+
+  hold on;
+
+  if size(n, 2)==2
+      % Draw a 2 dimensional graph ----------------------
+
+      % Draw faces of the graph ------------
+      if ~strcmp(sf{1}, 'none') && ~isempty(f)
+          if iscell(f)
+              % each face is contained in a cell.
+              hf = zeros(size(f));
+              for fi=1:length(f)
+                  hf(fi) = patch('Faces', f{fi}, 'Vertices', n, sf{:});
+              end
+          else
+              % process faces as an Nf*N array. Nf is the number of faces,
+              % and all faces have the same number of vertices (nodes).
+              hf = patch('Faces', f, 'Vertices', n, sf{:});
+          end
+      end
+
+      % Draw 2D Edges ----------------------
+      if ~strcmp(se{1}, 'none') && size(e, 1)>0
+          he = plot([n(e(:,1),1) n(e(:,2),1)]', [n(e(:,1),2) n(e(:,2),2)]', se{:});
+      end
+
+      % Draw 2D nodes ----------------------
+      if ~strcmp(sn{1}, 'none')
+          hn = plot(n(:,1), n(:,2), sn{:});
+      end
+
+
+  elseif size(n, 2)==3
+      % Draw a 3 dimensional graph ----------------------
+
+      % use a zbuffer to avoid display pbms.
+      set(gcf, 'renderer', 'zbuffer');
+
+      % Draw 3D Faces ----------------------
+      if ~strcmp(sf{1}, 'none')
+          if iscell(f)
+              % each face is contained in a cell.
+              hf = zeros(size(f));
+              for fi=1:length(f)
+                  hf(fi) = patch('Faces', f{fi}, 'Vertices', n, sf{:});
+              end
+          else
+              % process faces as an Nf*N array. Nf i the number of faces,
+              % and all faces have the same number of vertices (nodes).
+              hf = patch('Faces', f, 'Vertices', n, sf{:});
+          end
+      end
+
+      % Draw 3D edges ----------------------
+      if ~strcmp(se{1}, 'none') && size(e, 1)>0
+  %         he = plot3(...
+  %             [n(e(:,1),1) n(e(:,2),1)]', ...
+  %             [n(e(:,1),2) n(e(:,2),2)]', ...
+  %             [n(e(:,1),3) n(e(:,2),3)]', ...
+  %             se{:});
+          he = line(...
+              [n(e(:,1),1) n(e(:,2),1)]', ...
+              [n(e(:,1),2) n(e(:,2),2)]', ...
+              [n(e(:,1),3) n(e(:,2),3)]', ...
+              se{:});
+      end
+
+      % Draw 3D nodes ----------------------
+      if ~strcmp(sn{1}, 'none');
+          hn = plot3(n(:,1), n(:,2), n(:,3), sn{:});
+      end
+
+  end
+
+
+  %% Format output arguments
+
+  % return handle to edges
+  if nargout==1
+      varargout{1} = he;
+  end
+
+  % return handle to nodes and edges
+  if nargout==2
+      varargout{1} = hn;
+      varargout{2} = he;
+  end
+
+  % return handle to nodes, edges and faces
+  if nargout==3
+      varargout{1} = hn;
+      varargout{2} = he;
+      varargout{3} = hf;
+  end
+
+
+
+endfunction
+
+function res = concatArguments(in1, in2)
+  % in1 is a cell array already initialized
+  % in2 is an argument that can be:
+  %   - empty
+  %   - the string 'none'
+  %   - another cell array
+
+  if isempty(in2)
+      res = in1;
+      return;
+  end
+
+  if ischar(in2)
+      if strcmp('none', in2)
+          res = {'none'};
+          return;
+      end
+  end
+
+  if iscell(in1)
+      res = [in1(:)' in2(:)'];
+  else
+      res = [{in1} in2(:)];
+  end
+
+endfunction