/usr/share/psychtoolbox-3/PsychOneliners/DotOffset.m is in psychtoolbox-3-common 3.0.9+svn2579.dfsg1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | % [dx,dy,dz,a,e] = DotOffset(r,d,ndots)
% computes DX, DY and DZ offsets to move a point in a direction specified
% by R. Output for NDOTS offsets are computed independently. Only azimuthal
% direction can be specified or both azimuth and elevation, in which case a
% number of different randomizations are possible (see third form of R
% below). D is the distance by with dots are to be offset and should be
% either scalar or have length NDOTS.
%
% all angles are in degrees
%
% Outputs A and E are the azimuth and elevation angles used by DotOffset
% for each offset. If only one output is requested, a 3xNDOTS output matrix
% with the x, y and z offset on the respective rows is returned.
%
% R can take four forms:
% - scalar: direction (in degrees) of offset in azimuth (0 is translation
% in z direction, 90 in x direction towards 3 o'clock), used for all
% outputted offsets
% - vector with length NDOTS: direction (in degrees) of offset in azimuth
% specified in input for each outputted offset
% - a matrix of size NDOTSx2: direction (in degrees) of offset in azimuth
% (first column) and elevation (second column) specified in input for
% each outputted offset
% - 2x2 cellmatrix: the first row specifies azimuth direction, the second
% the elevation angle. A number of different inputs for the azimuth and
% the elevation row are possible and lead to the following outputs:
% - first column is a vector with length NDOTS: direction (in degrees) of
% offset specified for each outputted offset. Second column is ignored.
% - first column is a vector with length other than NDOTS: for each
% outputted offset, offset direction is randomly selected from the
% values in the vector (see 'help RandSel'). Second column is ignored.
% - scalar in the first column and NaN in the second column (e.g.
% {45,NaN;67,NaN} or {45,90;67,NaN}). Direction specified in the first
% column is used for all outputted offsets.
% - scalar in the first and second column (both non-NaN) (e.g.
% {45,90;67,NaN} or {45,90;0,360}). For each offset, a random direction
% is chosen within the specified limits. Angles are randomly chosen
% between lower (1st column) and upper (2nd column) boundaries (see
% 'help RandLim').
%
% Function can also be used to compute points laying on (part of) a Circle
% or sphere with radius D:
% [X,~,Z] = DotOffset(linspace(0,360),D,100);
% 2008-07-29 DN wrote it.
% 2008-08-06 DN now included all possible inputs I could think of
% 2011-07-20 DN now supports specified azimuth and elevation for each dot
% without the complicated cell input syntax
function [dx,dy,dz,a,e] = DotOffset(r,d,ndots)
psychassert(length(d)==1 || length(d)==ndots,'Input D should be scalar or have length NDOTS');
if isscalar(r) && ~iscell(r)
e = 0;
a = r;
elseif isvector(r) && length(r)==ndots && ~iscell(r)
a = r(:).'; % assure row vector
e = 0;
elseif ~iscell(r) && all(size(r)==[ndots,2])
a = r(:,1).';
e = r(:,2).';
elseif iscell(r) && size(r,1)==2 && size(r,2)==2
% azimuth
if isvector(r{1,1}) && length(r{1,1})==ndots
% direction for each offset specified
a = r{1,1}(:).'; % assure row vector
elseif isvector(r{1,1}) && length(r{1,1})>1
% a set of directions to randomly draw from
a = RandSel(r{1,1},ndots);
elseif isnan(r{1,2}) || r{1,1}==r{1,2}
% scalar, same direction for all offsets
a = r{1,1};
else
% randomly compute direction betwee lower and upper boundaries
a = RandLim([1,ndots],r{1,1},r{1,2});
end
% elevation
if isvector(r{2,1}) && length(r{2,1})==ndots
e = r{2,1}(:).'; % assure row vector
elseif isvector(r{2,1}) && length(r{2,1})>1
e = RandSel(r{2,1},ndots);
elseif isnan(r{2,2}) || r{2,1}==r{2,2}
e = r{2,1};
else
e = RandLim([1,ndots],r{2,1},r{2,2});
end
else
error('Input not recognized: R must be scalar, a vector of length NDOTS, a NDOTSx2 matrix or a 2x2 cellmatrix')
end
% a is azimuth angle, e is elevation angle
dx = d .* cosd(e) .* sind(a);
dy = d .* sind(e);
dz = d .* cosd(e) .* cosd(a);
if isscalar(dx)
dx = dx*ones(1,ndots);
end
if isscalar(dy)
dy = dy*ones(1,ndots);
end
if isscalar(dz)
dz = dz*ones(1,ndots);
end
if nargout==1
% make a 3 x NDOTS output matrix
dx = [dx; dy; dz];
end
if isscalar(a) && nargout>=4
a = a*ones(1,ndots);
end
if isscalar(e) && nargout>=5
e = e*ones(1,ndots);
end
|