Tracking and Separation (Visual Depth Perception 11)

Manipulate[
nORM[vector_?VectorQ]:=(Sqrt[vector.vector]);
degrees[q_]:=q*180/π;
arcMinutes[q_]:=q*60*180/π;

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]]};

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


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]];

fixateConvergence[headAimVector_?VectorQ,fixate_?VectorQ,base_?VectorQ]:=(rightφ[headAimVector,fixate,base]-leftφ[headAimVector,fixate,base]);

leftα[headAimVector_?VectorQ,fixate_?VectorQ,base_?VectorQ]:=leftφ[headAimVector,fixate,base]-aimψ[headAimVector,base];
rightα[headAimVector_?VectorQ,fixate_?VectorQ,base_?VectorQ]:=rightφ[headAimVector,fixate,base]-aimψ[headAimVector,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]]];

convergenceDistraction[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=If[Or[Abs[leftφ[headAimVector,fixate, base]-leftδ[headAimVector,fixate, distraction,base]]>π/3.,Abs[rightφ[headAimVector,fixate, base]-rightδ[headAimVector,fixate, distraction,base]]>π/3.],0.0,(rightδ[headAimVector,fixate, distraction,base]-leftδ[headAimVector,fixate, distraction,base])];

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])];

rightθinside[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=rightθ[headAimVector,fixate,distraction,base]+ArcSin[nodePercent*Sin[rightθ[headAimVector,fixate,distraction,base]]];

leftθinside[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=leftθ[headAimVector,fixate,distraction,base]+ArcSin[nodePercent*Sin[leftθ[headAimVector,fixate,distraction,base]]];

retinalDisparity[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θinside[headAimVector,fixate,distraction,base]-leftθinside[headAimVector,fixate,distraction,base])];

eyePict[eyeCenter_?VectorQ,fixate_?VectorQ]:=Module[{λ,viewVector},viewVector=fixate-eyeCenter;
λ=ArcTan[viewVector[[1]],viewVector[[2]]];
viewVector=viewVector/nORM[viewVector];
Show[{Graphics[{AbsoluteThickness[2],Gray,Circle[eyeCenter,eyeRadius,{λ+.4,2π+λ-.4}]}],Graphics[{Gray,
Circle[eyeCenter+ .8eyeRadius viewVector,.5eyeRadius,{λ-1.5,λ+1.5}]}],
Graphics[{Green,
Disk[eyeCenter+eyeRadius*nodePercent*viewVector,eyeRadius/10]
}]
},AspectRatio->Automatic]];


eyeEdge[θ_]:=eyeRadius*{Cos[θ],Sin[θ]};

inRays[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=Show[{eyePict[leftEyeCenter[headAimVector, base],fixate],eyePict[rightEyeCenter[headAimVector,base],fixate],Graphics[{Red,{Line[{rightEyeNode[headAimVector,fixate,base],rightEyeCenter[headAimVector,base]-eyeRadius*rightViewVector[headAimVector,fixate,base]/nORM[rightViewVector[headAimVector,fixate,base]]}]}}],Graphics[{Red,{Line[{leftEyeNode[headAimVector,fixate,base],leftEyeCenter[headAimVector, base]-eyeRadius*leftViewVector[headAimVector,fixate,base]/nORM[leftViewVector[headAimVector,fixate,base]]}]}}],Graphics[{Blue,{Line[{rightEyeNode[headAimVector,fixate,base],rightEyeCenter[headAimVector,base]+eyeEdge[rightφ[headAimVector,fixate,base]-π-rightθinside[headAimVector,fixate,distraction,base]]}]}}],
Graphics[{Blue,{Line[{leftEyeNode[headAimVector,fixate,base],leftEyeCenter[headAimVector,base]+eyeEdge[leftφ[headAimVector,fixate,base]-π-leftθinside[headAimVector,fixate,distraction,base]]}]}}],
Graphics[{Purple,{Line[{rightEyeCenter[headAimVector,base],rightEyeCenter[headAimVector,base]+eyeEdge[rightφ[headAimVector,fixate,base]-π-rightθinside[headAimVector,fixate,distraction,base]]}]}}],
Graphics[{Purple,{Line[{leftEyeCenter[headAimVector,base],leftEyeCenter[headAimVector,base]+eyeEdge[leftφ[headAimVector,fixate,base]-π-leftθinside[headAimVector,fixate,distraction,base]]}]}}],
Graphics[{Green,{Line[N[{leftEyeCenter[headAimVector, base],rightEyeCenter[headAimVector, base]}]]}}],
min=Min[{leftφ[headAimVector,fixate,base]-π-leftθinside[headAimVector,fixate,distraction,base]-retinalDisparity[headAimVector,fixate,distraction,base],leftφ[headAimVector,fixate,base]-π-leftθinside[headAimVector,fixate,distraction,base]}];
MAX=Max[{leftφ[headAimVector,fixate,base]-π-leftθinside[headAimVector,fixate,distraction,base]-retinalDisparity[headAimVector,fixate,distraction,base],leftφ[headAimVector,fixate,base]-π-leftθinside[headAimVector,fixate,distraction,base]}];
Graphics[{Brown,AbsoluteThickness[3],{Circle[leftEyeCenter[headAimVector, base],eyeRadius,{min,MAX}]}}]
},AspectRatio->Automatic,PlotRange->{{midPoint[headAimVector,base][[1]]-interOcular,midPoint[headAimVector,base][[1]]+interOcular},{midPoint[headAimVector,base][[2]]-interOcular,midPoint[headAimVector,base][[2]]+interOcular}}];

outRays[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=Show[{Graphics[{Red,AbsolutePointSize[4],{Point[N[fixate]]}}],Graphics[{Blue,AbsolutePointSize[4],{Point[N[distraction]]}}],Graphics[{Red,{Line[N[{fixate,rightEyeNode[headAimVector,fixate, base]}]]}}],Graphics[{Red,{Line[N[{fixate,leftEyeNode[headAimVector,fixate, base]}]]}}],Graphics[{Blue,{Line[N[{distraction,rightEyeNode[headAimVector,fixate, base]}]]}}],Graphics[{Blue,{Line[N[{distraction,leftEyeNode[headAimVector,fixate, base]}]]}}],
Graphics[{Green,{Line[N[{headAimVector,base}]]}}]
},AspectRatio->Automatic];

outLabels[aimHead_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=
Show[{Graphics[{Magenta,{Text[StringForm["(Subscript[θ, r]) = `1`°",Round[N[(180/π)rightθ[aimHead,fixate,distraction,base]],.1]],{.7,0}+rightEyeNode[aimHead,fixate,base]-2.5eyeRadius(rightEyeCenter[aimHead,base]-distraction-fixate)/nORM[(rightEyeCenter[aimHead,base]-distraction-fixate)]]
,
Circle[rightEyeNode[aimHead,fixate,base],2.5eyeRadius,{Min[rightδ[aimHead,fixate,distraction,base],rightφ[aimHead,fixate,base]],Max[rightδ[aimHead,fixate,distraction,base],rightφ[aimHead,fixate,base]]}]
}}]
},AspectRatio->Automatic];
(*Real Program Starts Here*)
interOcular=6.5;
eyeRadius=1.3;
aimOffset=0;
base[t_]={t,0};
aimHead={0,1};
f=fixate[[2]];(*fixate={0,f};*)
Show[{
inRays[aimHead,fixate,distraction,base[t]]
,
outLabels[aimHead,fixate,distraction,base[t]]
,
Graphics[{AbsolutePointSize[4],Point[midPoint[aimHead,base[t]]]}]
,
Graphics[{Green,AbsolutePointSize[4],{Point[base[t]],
Text["B",base[t]-{0,.5}],
Text["A",1.05aimHead+{0,.5}+base[t]],Line[{base[t],aimHead+base[t],base[t]+{.1,.7}}]
}}],
Graphics[{Orange,
{Circle[rightEyeNode[aimHead,fixate,base[t]],1.5eyeRadius,{Min[{aimψ[aimHead,base[t]],rightφ[aimHead,fixate,base[t]]}],Max[{aimψ[aimHead,base[t]],rightφ[aimHead,fixate,base[t]]}]}]
,
Line[{rightEyeNode[aimHead,fixate,base[t]],rightEyeNode[aimHead,fixate,base[t]]+3aimHead}]
,
Text[StringForm["(Subscript[α, r]) = `1` °",Round[N[rightα[aimHead,fixate,base[t]]180/π],.1]],rightEyeNode[aimHead,fixate,base[t]]+2aimHead+{.8,0}]
}}]
,
Graphics[{Red,AbsolutePointSize[4],{Point[fixate],Text[StringForm["F = (`1`  ,  `2`)",Round[fixate[[1]],.01],Round[fixate[[2]],.01]],fixate+{-1,.5}],Line[{leftEyeNode[aimHead,fixate,base[t]],fixate}],Line[{rightEyeNode[aimHead,fixate,base[t]],fixate}]}}]
,
Graphics[{Blue,AbsolutePointSize[5],{Point[distraction],Text[StringForm["D = (`1`  ,  `2`)",Round[distraction[[1]],.01],Round[distraction[[2]]],.01],distraction+{-1,.5}],Line[{leftEyeNode[aimHead,fixate,base[t]],distraction}],Line[{rightEyeNode[aimHead,fixate,base[t]],distraction}]}}]
,
Graphics[{Brown,
{Text[StringForm["(Subscript[β, r]) = `1` °",Round[N[(rightα[aimHead,fixate,base[t]]-rightθ[aimHead,fixate,distraction,base[t]])180/π],.1]],rightEyeNode[aimHead,fixate,base[t]]+{-.6,0}-2.eyeRadius((rightEyeNode[aimHead,fixate,base[t]]-distraction)/nORM[(rightEyeNode[aimHead,fixate,base[t]]-distraction)])]
,
Circle[rightEyeNode[aimHead,fixate,base[t]],2.eyeRadius,{Min[{aimψ[aimHead,base[t]],rightδ[aimHead,fixate,distraction,base[t]]}],Max[{aimψ[aimHead,base[t]],rightδ[aimHead,fixate,distraction,base[t]]}]}]}}],
Graphics[{AbsoluteThickness[2],Dashing[.025],Gray,
{Arrow[{base[t]+{-1,-1},base[t]+{1,-1}}]
}}]
,
Graphics[{Text["Translation",base[t]+{-.1,-1.5}]}]

},PlotRange->{2{-3.25,3.25},{-2,12}},AspectRatio->Automatic,ImageSize->{400,400}]

,
{{fixate,{-1,8}},{-6,5},{6,11},Locator},
{{distraction,{1,9}},{-6,5},{6,11},Locator},
{{nodePercent,.5,"node percent"},0,1.,Appearance->"Labeled"},
{{t,0,"time t"},-4,4,Appearance->"Labeled"},TrackedSymbols->Manipulate]

CAPTION

We study the case of an observer moving at right angles to the aim of the head, fixing his eyes on a (fixate) point F and also observing a distractor D. The important angles for depth perception by motion parallax are θ and α. The angle β=α-θ is mathematically helpful.

To animate motion in time, click the [+] next to the "time t" slider and click play [>]. The changing position of the distractor on the retina is "motion parallax".

DETAILS

Fixation on F=(0,f) causes the eyes to rotate because of the observer's continuous translation. We measure the tracking angle α counterclockwise (+) from the y axis (head aim direction) and call the time rate of change needed to maintain fixation the "pursuit". This is ((d α)/(d t)), the time derivative in the sense of calculus.

In terms of the eye parameters n = node percent, i = interocular distance, and r = eye radius, the derivative is

((d α)/(d t))(t) =((i (f+n r))/((((f+n r))^2)+(i^2) (t^2))).

This peaks at t=0 (when the denominator is largest):

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

The observer's translation also causes the angle separating the fixate and distraction to change, causing motion of the image of D on the retina. The time rate of change in angle θ from the distractor to the fixate is a "dynamic parallax" describing the moving retinal image of D=((Subscript[d, 1]),(Subscript[d, 2])). This derivative is

((d θ)/(d t))=(i ((f+n r) (Sqrt[(f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)]) (Subscript[d, 1]^2)+(-(n^3) (r^3)+(n^2) (Sqrt[(f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)]) (r^2)+2 f n ((Sqrt[(f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)])-n r) r+(f^2) ((Sqrt[(f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)])-n r)-(i^2) (t^2) (Sqrt[(f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)])) (Subscript[d, 1])+(f+n r) (Subscript[d, 2]) (i t (2 (Sqrt[(f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)])-n r)+(Sqrt[(f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)]) (Subscript[d, 2]))))/((Sqrt[(f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)]) (((f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)) (Subscript[d, 1]^2)+2 (f+n r) ((f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)-n r (Sqrt[(f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)])) (Subscript[d, 1])+((f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)) (Subscript[d, 2]^2)+((f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)) ((f^2)+2 n r f+2 (n^2) (r^2)+(i^2) (t^2)-2 n r (Sqrt[(f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)]))+2 i t ((f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)-n r (Sqrt[(f^2)+2 n r f+(n^2) (r^2)+(i^2) (t^2)])) (Subscript[d, 2]))).

This simplifies greatly at the time t=0, when the eye crosses the (Subscript[d, 1]) axis:

((d θ)/(d t))(0) =(((((Subscript[d, 1])^2)+((Subscript[d, 2])^2)+(Subscript[d, 1]) f) i)/((((((Subscript[d, 1])+f))^2)+((Subscript[d, 2])^2)) (f+n r))).

When the distraction is in line with the eye, (Subscript[d, 2])=0, and ((d θ)/(d t))(0) has the simple form

((d θ)/(d t))(0) =((i (Subscript[d, 1]))/(((Subscript[d, 1])+f) (f+n r)))

and the ratio of retinal motion over pursuit is

((d θ)/(d α))(0) =((Subscript[d, 1])/(f+(Subscript[d, 1]))).

The basic case of the motion/pursuit law for relative depth from motion parallax is

((Subscript[d, 1])/f)=((d θ)/(d β))=((d θ)/(d α-d θ))=((d θ)/(d α))(1/(1-((d θ)/(d α)))).

THIS NOTEBOOK IS THE SOURCE CODE FROM

"Tracking and Separation (Visual Depth Perception 11)" from the Wolfram Demonstrations Project
 http://demonstrations.wolfram.com/TrackingAndSeparationVisualDepthPerception11/

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 »