ランダムドットステレオグラム

デモプログラムのStereoDemoを元に作っています。

StereoDemoは、ドットが運動したりガウシアン分布を使っていたりとちょっと複雑なので、もっとシンプルなものにしました。

ここで公開しているものは、四角形の中央に小さな四角形があって、その小さな四角形が大きな四角形よりも手前に見えたり奥に見えたりするプログラムです。

このプログラムは引数を1つとり、その引数によって描画モードが変わります。

例えば、

randomdot1(6)

として実行すると、stereoMode = 6 ですから、赤と緑のアナグリフになります。

詳しくはScreen('OpenWindow')を参照してください。

function randomdot1(stereoMode)
ListenChar(2);
AssertOpenGL;
%手作りfunction
%myKeyCheck;
%引数が与えられなかったらstereoModeを8にする
if nargin < 1
    stereoMode = 8;
end;
try
  %必要に応じてカーソルを消してください
  %HideCursor;
 
  screenNumber=max(Screen('Screens'));
  %ウィンドウでの呈示
  [windowPtr, windowRect]=Screen('OpenWindow', screenNumber, BlackIndex(screenNumber), [50, 50, 1000, 600], [], [], stereoMode);
 
  % -xmaxから+xmaxまでのピクセル数がランダムドットを描画する四角形の水平方向の大きさです。
  % 同様に-ymaxから+ymaxまでのピクセル数がランダムドットを描画する四角形の垂直方向の大きさです。
  xmax = 200;
  ymax = 200;
 
  %ランダムドットの数
  numDots = 300;
  %ドットの大きさ
  dotSize = 4;
  %ドットの色(白に設定しておくと自動的にアナグリフの色でドットが描画される)
  col1 = WhiteIndex(windowPtr);
  %像差量
  disparity = 4;
 
  %ドットのx座標
  dots(1, :) = 2*xmax*rand(1, numDots) - xmax;
  %ドットのy座標
  dots(2, :) = 2*ymax*rand(1, numDots) - ymax;
  %ドットの像差量(像差を持たないドットについては0を代入する)
  dots(3, :) = zeros(1, numDots);
  tmp = find((dots(1, :) > -xmax/2) & (dots(1, :) < xmax/2) & (dots(2, :) > -ymax/2) & (dots(2, :) < ymax/2));
  dots(3, tmp) = disparity;
 
  %ドットのアンチエイリアスのため
  Screen('BlendFunction', windowPtr, 'GL_SRC_ALPHA', 'GL_ONE_MINUS_SRC_ALPHA');
 
  %SelectStereoDrawBufferを使うと色の重なりも考慮してくれる
 
  %刺激A
  Screen('SelectStereoDrawBuffer', windowPtr, 0);
  Screen('DrawDots', windowPtr, dots(1:2, :) + [dots(3, :)/2; zeros(1, numDots)], dotSize, col1, [windowRect(3:4)/2], 1);
 
  %刺激B
  Screen('SelectStereoDrawBuffer', windowPtr, 1);
  Screen('DrawDots', windowPtr, dots(1:2, :) - [dots(3, :)/2; zeros(1, numDots)], dotSize, col1, [windowRect(3:4)/2], 1);
   
  Screen('Flip', windowPtr);
 
  %何かのキーを押したらプログラム終了
  KbWait;
    
  %終了処理
  Screen('CloseAll');
  ShowCursor;
  ListenChar(0);
 
catch
  Screen('CloseAll');
  ShowCursor;
  ListenChar(0);
end

刺激Aも刺激Bも同じ色、col1 = WhiteIndex(windowPtr) で描画されていることに注意してください。

WhiteIndexで描画すると、stereoModeの値によって、自動的に赤や緑や青で刺激が描画されます。

また刺激Aと刺激Bが重なり合う部分では、加法混色の原理に基づいた色が再現されます。

windowRect(3:4) / 2 は刺激を描画するウインドウの中心の座標になります。

ただしstereoModeが4または5のときには、ウインドウが左右に二分割されて、それぞれの中央に刺激が描画されます。

ドットの座標はdotsという行列で表されます。

1行目にはx座標が、

2行目にはy座標が、

3行目には像差量が

代入されています。

Screen('DrawDots') でドットを描画する際に、x座標に像差量を増減しています。y座標については像差量をもたないので、zerosでゼロ行列を作り足し合わせています。

以下の図も参考にしてください。青い点線で囲まれた四角形の領域が、黒い実線で囲まれた四角形より手前に見えたり奥に見えたりします。