function newRect = OffsetRect(oldRect,x,y) % newRect = OffsetRect(oldRect,x,y) % % Offset the passed rect matrix by the horizontal (x) % and vertical (y) shift given. You can also pass in column vectors x and y % with e.g., n different "shifts" and the function will return n copies of % oldRect, each shifted by one of the shift values in x and y. % % Alternatively you can give a single scalar x,y shift value, but apply it % to a whole matrix of rects 'oldRect' --> Apply a common offset to a large % number of rects simultaneously. % % Also see PsychRects. % 5/16/96 dhb Relented to Pelli's request to change calling order % from v,h to x,y. % dhb Index using RectTop etc. % 7/10/96 dgp Wrote it. % 8/5/96 dgp Check rect size. % 5/18/08 mk Vectorized. % 5/31/09 mk Improved error handling. Add support for offsetting a % single rect multiple times, ie., pass x,y as vectors, then % create many offset versions of single input rect. % 1/17/16 mscain Resolve ambiguity for 4x4 matrix to fix failure. if nargin~=3 error('Usage: newRect = OffsetRect(oldRect,x,y)'); end if numel(oldRect) == 4 % Single rect case: if ~(isrow(oldRect) || iscolumn(oldRect)) error('Wrong size rect argument. A single rect must be a 4 element row or column vector!'); end if length(x)==1 && length(y)==1 % Single rect, offset by a single (x,y) point: newRect(RectTop) = oldRect(RectTop) + y; newRect(RectBottom) = oldRect(RectBottom) + y; newRect(RectLeft) = oldRect(RectLeft) + x; newRect(RectRight) = oldRect(RectRight) + x; else % Single rect, but multiple points: if ~all(size(x) == size(y)) || ~iscolumn(x) error('Wrong format of x or y in multipoint case: x and y must be 1-column vectors of matching size!'); end if isrow(oldRect) % x and y are one column vectors with size(x,1) rows/elements. % Replicate oldRect row into nrpts rows of identical copies, then % add point offsets: newRect = repmat(oldRect, size(x, 1), 1) + [x, y, x, y]; else % x and y are one column vectors with size(x,1) rows/elements. % Replicate oldRect column into nrpts columns of identical copies, then % add point offsets: newRect = repmat(oldRect, 1, size(x, 1)) + [x, y, x, y]'; end end else % Multirect case: Offsets (x,y) can be vectors, or a single point: % A 4x4 matrix is a special case, treated as 4 rects in 4 rows to % resolve the ambiguity, as proposed by GitHub user mscain. if size(oldRect, 1)==4 && size(oldRect, 2)~=4 newRect(RectTop, :) = oldRect(RectTop, :) + y; newRect(RectBottom, :) = oldRect(RectBottom, :) + y; newRect(RectLeft, :) = oldRect(RectLeft, :) + x; newRect(RectRight, :) = oldRect(RectRight, :) + x; else newRect(:, RectTop) = oldRect(:, RectTop) + y; newRect(:, RectBottom) = oldRect(:, RectBottom) + y; newRect(:, RectLeft) = oldRect(:, RectLeft) + x; newRect(:, RectRight) = oldRect(:, RectRight) + x; end end