function cellRects=ArrangeRects(n,objectRect,windowRect,rightToLeft); % cellRects=ArrangeRects(n,objectRect,windowRect,[rightToLeft]); % % Returns an array of n contiguous rects that achieve a visually % pleasing arrangement of n objects of size objectRect within a % window of size windowRect. Each row of the returned matrix is a rect. % If the rightToLeft argument is supplied and nonzero then % the cells are ordered right to left (like Hebrew letters). % Otherwise they are ordered left to right (like English letters). % The result depends on the proportions of the objectRect, but is % independent of its size and position. % Also see PsychRects. % 5/12/96 dgp Wrote it, based on my Alphabet.c in TextInNoise. % 5/16/96 dgp Updated it to work with 1x4, instead of 4x1, rect. % 5/27/96 dgp more explanation. % 7/10/96 dgp PsychRects % Explanation: % Distribute n objects of size objectRect in a window of size windowRect. % We're making a table. The row and column spacings are uniform but need not be equal. % We want a regular grid with uniform horizontal and vertical spaces between objects. % All rows are fully occupied except the last, which is centered, but still grid-aligned. % Here's the rationale for the calculation. % ry=ratio of window to object heights. % rx=ratio of window to object width. % a=ry/rx % We need to determine how many rows (ny) and columns (nx) we want. % To show all the n objects we need nx*ny>=n, but we want as little excess as possible % because excess cells will be blank, wasting space. % To achieve similar gaps vertically and horizontally between objects % we want the ratio ny/nx to be approximately equal to the ratio ry/rx=a. % Multiplying together the two approximate relations gives us ny*ny=a*n, i.e. ny=sqrt(n*a). % Dividing them gives us nx=sqrt(n/a). % We then alternately find the smallest integers nx and ny with a product of at least than n. if nargin<3 || nargin>4 error('Usage: cellRects=ArrangeRects(n,objectRect,windowRect,[rightToLeft]);'); end if size(objectRect,2)~=4 || size(windowRect,2)~=4 error('Wrong size rect argument. Usage: cellRects=ArrangeRects(n,objectRect,windowRect,[rightToLeft]);'); end if nargin<4 rightToLeft=0; end r=windowRect; a=(RectHeight(r)/RectWidth(r))/(RectHeight(objectRect)/RectWidth(objectRect)); if(a>1) nx=ceil(sqrt(n/a)); ny=ceil(n/nx); nx=ceil(n/ny); else ny=ceil(sqrt(n*a)); nx=ceil(n/ny); end ny=ceil(n/nx); empties=nx*ny-n; % create a cell for each object cellHeight=RectHeight(windowRect)/ny; cellWidth=RectWidth(windowRect)/nx; xx=1:nx; if(rightToLeft) xx=fliplr(xx); end i=1; cellRects=zeros(n,4); for y=1:ny; for x=xx; cellRect=SetRect(0,0,cellWidth,cellHeight); cellRect=OffsetRect(cellRect,windowRect(RectLeft),windowRect(RectTop)); cellRect=OffsetRect(cellRect,(x-1)*cellWidth,(y-1)*cellHeight); if(y=floor(empties/2) && nx-x>=ceil(empties/2) ) ) cellRects(i,:)=cellRect; i=i+1; if(i>n)break;end; end end end