Mercurial > hg > camir-aes2014
diff toolboxes/graph_visualisation/graphViz4Matlab/layouts/Randlayout.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/graph_visualisation/graphViz4Matlab/layouts/Randlayout.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,134 @@ +classdef Randlayout < Abstractlayout +% A greedy, random layout - gives a different layout each time its called. +% Matthew Dunham +% University of British Columbia +% http://www.cs.ubc.ca/~mdunham/ + + properties + xmin; % The left most point on the graph axis in data units + xmax; % The right most point on the graph axis in data units + ymin; % The bottom most point on the graph axis in data units + ymax; % The top most point on the graph axis in data units + adjMatrix; % The adjacency matrix + maxNodeSize; % The maximum diameter of a node in data units + image; % An image for the button that will lanuch this layout + name; % A unique name for instances of this class + shortDescription; % A description for use in the tooltips + nodeSize; % The calculated node size, call dolayout() before accessing + centers; % The calculated node centers in an n-by-2 matrix + seed; % The seed used to generate the last layout. + end + + + + methods + + function obj = Randlayout(name,seed) + % constructor - seed is optional. + if(nargin < 1) + obj.name = 'Randlayout'; + else + obj.name = name; + end + if(nargin < 2) + seed = 31; + end + obj.seed = seed; + load glicons + obj.image = icons.random; + obj.shortDescription = 'Random Greedy Layout'; + + end + end + + methods(Access = 'protected') + + function calcLayout(obj) + rand('twister',obj.seed); randn('state',obj.seed); + obj.seed = obj.seed + 1; + nnodes = size(obj.adjMatrix,1); + obj.nodeSize = min(obj.maxNodeSize,2*(obj.xmax-obj.xmin)/nnodes); + npoints = 25; + locdist = ones(npoints,npoints); + c = floor(0.4*npoints):ceil(0.6*npoints); + locdist(c,c) = 1.5; % slightly favour the center + locdist = locdist./sum(locdist(:)); % discrete distribution over locations + locations = zeros(nnodes,2); % holds indices into locdist + nsize = ceil(npoints*(obj.nodeSize/2)/(obj.xmax - obj.xmin+obj.nodeSize)); + for i=1:nnodes + while(true) + [xcandidate,ycandidate] = obj.sample(locdist); + [valid,locdist] = obj.isfree(xcandidate,ycandidate,locdist,nsize); + if(valid) + locations(i,:) = [xcandidate,ycandidate]; + locdist = obj.radiate(locdist,locations,npoints); + break; + end + end + end + nedges = sum(obj.adjMatrix,1) + sum(obj.adjMatrix,2)'; + [val,perm] = sort(nedges,'descend'); + locations = locations(perm,:); + obj.mapLocationsToAxes(locations,npoints); + end + + function mapLocationsToAxes(obj,locations,npoints) + % Map sampled locations on a grid to actual points on the graph + % axes. + xndx = locations(:,1); yndx = locations(:,2); + xmin = obj.xmin + obj.nodeSize/2; + xmax = obj.xmax - obj.nodeSize/2; + ymin = obj.ymin + obj.nodeSize/2; + ymax = obj.ymax - obj.nodeSize/2; + xstep = (xmax - xmin) /npoints; + ystep = (ymax - ymin) /npoints; + xpos = xmin+xstep:xstep:xmax; + ypos = ymin+ystep:ystep:ymax; + obj.centers = [xpos(xndx)',ypos(yndx)']; + end + + function [valid,locdist2] = isfree(obj,xcandidate,ycandidate,locdist,nsize) + % Check if the sampled location is valid. Regardless, zero out the + % spot so that we don't sample from here again. + xndx = max(1,xcandidate-nsize):min(xcandidate+nsize,size(locdist,2)); + yndx = max(1,ycandidate-nsize):min(ycandidate+nsize,size(locdist,1)); + nodeArea = locdist(xndx,yndx); + valid = all(nodeArea(:)); + locdist2 = locdist; + locdist2(xndx,yndx) = 0; + locdist2 = locdist2 ./sum(locdist(:)); + end + + function locdist = radiate(obj,locdist,locations,npoints) + % Update the location probability distribution. + n = nnz(locations(:,1)); + loczeros = locdist == 0; + for i=1:n + [x y] = meshgrid(1:npoints,1:npoints); + x = x(:); y = y(:); + dist = sqrt((x-locations(i,1)).^2 + (y-locations(i,2)).^2); + locdist = locdist + reshape(dist,npoints,npoints)'; + end + locdist(loczeros) = 0; + locdist = locdist ./sum(locdist(:)); + end + + function [xndx,yndx] = sample(obj,dist) + % Sample a single value from the non-uniform discrete distribution. + if(isnan(dist(1))) + perm = randperm(size(dist,1)); + xndx = perm(1); + yndx = perm(2); + return; + end + r = rand; + cumprob = cumsum(dist(:)); + s = sum(r > cumprob(1:end-1)) + 1; + [xndx,yndx] = ind2sub(size(dist),s); + end + + end + + + +end \ No newline at end of file