Motion Parallax versus Depth, 2D (Visual Depth Perception 12)

Manipulate[
Module[{r,i,n,nORM,degrees,arcMinutes,eyeRadius,interOcular,aimOffset,nodePercent,aimψ,midPoint,rightEyeCenter,leftEyeCenter,rightViewVector,rightφ,rightEyeNode,leftViewVector,leftφ,leftEyeNode,rightDistractVector,rightδ,leftDistractVector,leftδ,rightθ,leftθ,binocularDisparity,f,Δ,c,dα,fGraph,αGraph},
r=13/10;i=13/2;n=1/2;nORM[vector_?VectorQ]:=(Sqrt[vector.vector]);
degrees[q_]:=q*180/π;
arcMinutes[q_]:=q*60*180/π;
eyeRadius=(13/10);interOcular=(13/2);aimOffset=(1/8);nodePercent=1;
aimψ[headAimVector_?VectorQ,base_?VectorQ]:=ArcTan[headAimVector[[1]],headAimVector[[2]]];

midPoint[headAimVector_?VectorQ,base_?VectorQ]:=base-aimOffset*interOcular*{headAimVector[[2]],-headAimVector[[1]]};

rightEyeCenter[headAimVector_?VectorQ,base_?VectorQ]:=base+((1/2)-aimOffset)*interOcular*{headAimVector[[2]],-headAimVector[[1]]}/nORM[headAimVector];

leftEyeCenter[headAimVector_?VectorQ,base_?VectorQ]:=base-((1/2)+aimOffset)*interOcular*{headAimVector[[2]],-headAimVector[[1]]}/nORM[headAimVector];
rightViewVector[headAimVector_?VectorQ,fixate_?VectorQ,base_?VectorQ]:=fixate-rightEyeCenter[headAimVector, base];

rightφ[headAimVector_?VectorQ,fixate_?VectorQ,base_?VectorQ]:=ArcTan[rightViewVector[headAimVector, fixate, base][[1]],rightViewVector[headAimVector, fixate, base][[2]]];

rightEyeNode[headAimVector_?VectorQ,fixate_?VectorQ,base_?VectorQ]:=rightEyeCenter[headAimVector, base]+nodePercent*eyeRadius*rightViewVector[headAimVector,fixate, base]/nORM[rightViewVector[headAimVector, fixate, base]];

leftViewVector[headAimVector_?VectorQ,fixate_?VectorQ,base_?VectorQ]:=fixate-leftEyeCenter[headAimVector, base];

leftφ[headAimVector_?VectorQ,fixate_?VectorQ,base_?VectorQ]:=ArcTan[leftViewVector[headAimVector, fixate, base][[1]],leftViewVector[headAimVector, fixate, base][[2]]];

leftEyeNode[headAimVector_?VectorQ,fixate_?VectorQ,base_?VectorQ]:=leftEyeCenter[headAimVector, base]+nodePercent*eyeRadius*leftViewVector[headAimVector, fixate, base]/nORM[leftViewVector[headAimVector, fixate, base]];

rightDistractVector[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=distraction-rightEyeNode[headAimVector,fixate, base];

rightδ[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=ArcTan[rightDistractVector[headAimVector,fixate,distraction,base][[1]],rightDistractVector[headAimVector,fixate,distraction,base][[2]]];

leftDistractVector[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=distraction-leftEyeNode[headAimVector,fixate, base];

leftδ[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=ArcTan[leftDistractVector[headAimVector,fixate,distraction,base][[1]],leftDistractVector[headAimVector,fixate,distraction,base][[2]]];


rightθ[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=(rightφ[headAimVector,fixate, base]-rightδ[headAimVector,fixate,distraction,base]);

leftθ[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=(leftφ[headAimVector,fixate, base]-leftδ[headAimVector,fixate,distraction,base]);

binocularDisparity[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=If[Or[leftθ[headAimVector,fixate,distraction,base]<-π/2.,leftθ[headAimVector,fixate,distraction,base]>π/3.,rightθ[headAimVector,fixate,distraction,base]<-π/3.,rightθ[headAimVector,fixate,distraction,base]>π/2.],0,(rightθ[headAimVector,fixate,distraction,base]-leftθ[headAimVector,fixate,distraction,base])];
f[Δ_]=((Δ i/c-n r(1+Δ))/(1+Δ));
dα[Δ_]=degrees[c (1+(1/Δ))];
c=π/180.;
fGraph=ParametricPlot[{f[Δ],Δ},{Δ,0,1},AspectRatio->1/GoldenRatio,PlotStyle->{AbsoluteThickness[2],Blue},AxesLabel->{Style["f",Italic],Style["d",Italic]/Style["f",Italic]}];
αGraph=ParametricPlot[{180/π i/f[Δ],Δ},{Δ,.01,1},AspectRatio->1/GoldenRatio,AxesOrigin->{0,0},PlotStyle->{AbsoluteThickness[2],Purple},AxesLabel->{HoldForm[d α/(d t)],Style["d",Italic]/Style["f",Italic]}];
GraphicsGrid[{{
Show[{fGraph,Graphics[{Brown,{Text[Row[{Style["f",Italic]," = ",Round[f[depth],.1]}],{f[depth]+15,.1}],Text[Row[{((Style["d",Italic])/(Style["f",Italic]))," = ",Round[depth,.01],", ", Style["d",Italic]," = ",Round[f[depth] depth,.1]}],{30,depth+.2}],Text[Row[{HoldForm[d θ/(d t)]," = ",degrees[(((depth f[depth]) i)/((depth+1)f[depth] (f[depth]+n r)))]}],{f[depth]-15,depth+.05}],Text[Row[{"B.D."," = ",
Round[
degrees[binocularDisparity[{0,1},{0,f[depth]},{0,f[depth](1+depth)},{0,0}]],.0001]}],{f[depth]+20,depth-.02}],Line[{{0,depth},{f[depth],depth},{f[depth],0}}]}}]}]
},{
Show[{αGraph,
Graphics[{Brown,{Text[Row[{HoldForm[d α/(d t)]," = ",Round[dα[depth],.1]}],{dα[depth]+1,.1}],Text[Row[{((Style["d",Italic])/(Style["f",Italic]))," = ",Round[depth,.01]}],{1,depth+.1}],Text[Row[{HoldForm[d θ/(d t)]," = ",degrees[(((depth f[depth]) i)/((depth+1)f[depth] (f[depth]+n r)))]}],{dα[depth]+1,depth}],Line[{
{0,depth},{180/π i/f[depth],depth},{180/π i/f[depth],0}}]}}]}]}},ImageSize->{400,450}]]
,{{depth,.5,"relative depth"},.1,1,Appearance->"Labeled"}]

CAPTION

This Demonstration lets you move the relative distance between 0 and 1 and uses the formulas below to find the fixate distance f and pursuit rate d α/d t, keeping the motion d θ/d t=1°.

The program computes the binocular disparity of a fixed observer at the t=0 position. Notice that B.D.≈d θ/d t.

DETAILS

The retinal motion of a distractor viewed by a translating observer is not sufficient by itself to determine the relative depth of an object. This is similar to the static situation where binocular disparity does not determine depth by itself, but together with convergence does determine it.

Consider the case where the fixate and distractor lie on the y axis and the observer moves to the right along the x axis at 6.5 cm/sec (interocular distance/sec). Suppose the right eye crosses the y axis at t=0 as shown next.

The derivative in terms of the eye parameters, n = node percent, i = interocular distance, and r = eye radius at t=0 is

((d θ)/(d t))(0)=((i d)/((d+f) (f+n r))).

Solving ((d θ)/(d t))=c for (d/f) gives

(d/f)=((f+n r)/(i/c-(f+n r))).

Solving the equation Δ=((f+n r)/(i/c-(f+n r))) for f gives f=((Δ i/c-n r(1+Δ))/(1+Δ)).

Define the function f(Δ)=((Δ i/c-n r(1+Δ))/(1+Δ)); then ((d θ)/(d t))=c at fixate {0,f(Δ)} and distractor {0,f(Δ)(1+Δ)} for all values of Δ.

For fixate and distractor on the y axis,

((d α)/(d t))(0)=(i/(f+n r)), and when ((d θ)/(d t))=c, ((d α)/(d t))(0)=(i/(f(Δ)+n r))=c(1+(1/Δ)).

The Demonstration "Motion Parallax versus Depth, 3D (Visual Depth Perception 13)" (see Related Links) shows both fixate distance and pursuit on a single 3D curve.

The Demonstration "Motion/Pursuit Law in 1D (Visual Depth Perception 1)" (see Related Links) shows how the ratio of motion to pursuit does determine relative depth in this basic case.

THIS NOTEBOOK IS THE SOURCE CODE FROM

"Motion Parallax versus Depth, 2D (Visual Depth Perception 12)" from the Wolfram Demonstrations Project
 http://demonstrations.wolfram.com/MotionParallaxVersusDepth2DVisualDepthPerception12/

Contributed by: Keith Stroyan

A full-function Wolfram Mathematica system (Version 6 or higher) is required to edit this notebook.
GET WOLFRAM MATHEMATICA »

© Wolfram Demonstrations Project & Contributors   |   Terms of Use   |   Make a new version of this Demonstration »