Eye Parameters (Visual Depth Perception 6)

Manipulate[
Module[{nORM,degrees,arcMinutes,aimψ,midPoint,rightEyeCenter,leftEyeCenter,rightViewVector,rightφ,rightEyeNode,leftViewVector,leftφ,leftEyeNode,fixateConvergence,leftα,rightα,rightDistractVector,rightδ,leftδ,leftDistractVector,convergenceDistraction,rightθ,leftθ,binocularDisparity,rightθinside,leftθinside,retinalDisparity,eDGE,antiEDGE,rADIUS,cENTER,cIRCLE,eyePict,eyeEdge,min,MAX,inLabels,outRays,outLabels,inRays,headAimVector},
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])];

eDGE[L_?VectorQ,R_?VectorQ,F_?VectorQ]:=Module[{a,bX,bY,c,r},
a=Det[{{L[[1]],R[[1]],F[[1]]},{L[[2]],R[[2]],F[[2]]},{1,1,1}}];
bX=Det[{{L.L,R.R,F.F},{L[[2]],R[[2]],F[[2]]},{1,1,1}}];
bY=Det[{{L[[1]],R[[1]],F[[1]]},{L.L,R.R,F.F},{1,1,1}}];
c=-Det[{{L.L,R.R,F.F},{L[[1]],R[[1]],F[[1]]},{L[[2]],R[[2]],F[[2]]}}];
{bX,bY}/(2 a)+{((Sqrt[(bX^2)+(bY^2)-4 a c])/(2Abs[a])),0}];
antiEDGE[L_?VectorQ,R_?VectorQ,F_?VectorQ]:=Module[{a,bX,bY,c,r},
a=Det[{{L[[1]],R[[1]],F[[1]]},{L[[2]],R[[2]],F[[2]]},{1,1,1}}];
bX=Det[{{L.L,R.R,F.F},{L[[2]],R[[2]],F[[2]]},{1,1,1}}];
bY=Det[{{L[[1]],R[[1]],F[[1]]},{L.L,R.R,F.F},{1,1,1}}];
c=-Det[{{L.L,R.R,F.F},{L[[1]],R[[1]],F[[1]]},{L[[2]],R[[2]],F[[2]]}}];
{bX,bY}/(2 a)-{((Sqrt[(bX^2)+(bY^2)-4 a c])/(2Abs[a])),0}];
rADIUS[L_?VectorQ,R_?VectorQ,F_?VectorQ]:=Module[{a,bX,bY,c,r},
a=Det[{{L[[1]],R[[1]],F[[1]]},{L[[2]],R[[2]],F[[2]]},{1,1,1}}];
bX=Det[{{L.L,R.R,F.F},{L[[2]],R[[2]],F[[2]]},{1,1,1}}];
bY=Det[{{L[[1]],R[[1]],F[[1]]},{L.L,R.R,F.F},{1,1,1}}];
c=-Det[{{L.L,R.R,F.F},{L[[1]],R[[1]],F[[1]]},{L[[2]],R[[2]],F[[2]]}}];
((Sqrt[(bX^2)+(bY^2)-4 a c])/(2Abs[a]))];
cENTER[L_?VectorQ,R_?VectorQ,F_?VectorQ]:=Module[{a,bX,bY,c,r},
a=Det[{{L[[1]],R[[1]],F[[1]]},{L[[2]],R[[2]],F[[2]]},{1,1,1}}];
bX=Det[{{L.L,R.R,F.F},{L[[2]],R[[2]],F[[2]]},{1,1,1}}];
bY=Det[{{L[[1]],R[[1]],F[[1]]},{L.L,R.R,F.F},{1,1,1}}];
c=-Det[{{L.L,R.R,F.F},{L[[1]],R[[1]],F[[1]]},{L[[2]],R[[2]],F[[2]]}}];
{bX,bY}/(2 a)];
cIRCLE[L_?VectorQ,R_?VectorQ,F_?VectorQ]:=Module[{a,bX,bY,c,r},
a=Det[{{L[[1]],R[[1]],F[[1]]},{L[[2]],R[[2]],F[[2]]},{1,1,1}}];
bX=Det[{{L.L,R.R,F.F},{L[[2]],R[[2]],F[[2]]},{1,1,1}}];
bY=Det[{{L[[1]],R[[1]],F[[1]]},{L.L,R.R,F.F},{1,1,1}}];
c=-Det[{{L.L,R.R,F.F},{L[[1]],R[[1]],F[[1]]},{L[[2]],R[[2]],F[[2]]}}];
Circle[{bX,bY}/(2 a),((Sqrt[(bX^2)+(bY^2)-4 a c])/(2Abs[a]))]];


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,Sort@{λ+.4,2π+λ-.4}]}],Graphics[{Gray,
Circle[eyeCenter+ .8eyeRadius viewVector,.5eyeRadius,Sort@{λ-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,Sort@{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}}];

inLabels[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=Show[{Graphics[{Purple,Text[StringForm["(Subscript[θ, r]^i) = `1`",Round[N[degrees[rightθinside[headAimVector,fixate,distraction,base]]]]],rightEyeCenter[headAimVector,base]+1.5eyeRadius(rightEyeCenter[headAimVector,base]-distraction)/nORM[(rightEyeCenter[headAimVector,base]-distraction)]]}],Graphics[{Purple,Text[StringForm["(Subscript[θ, l]^i) = `1`",Round[N[degrees[leftθinside[headAimVector,fixate,distraction,base]]]]],leftEyeCenter[headAimVector, base]+1.5eyeRadius(leftEyeCenter[headAimVector,base]-distraction)/nORM[(leftEyeCenter[headAimVector,base]-distraction)]]}]}];


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[{base,headAimVector+base}]}}]
},AspectRatio->Automatic];

outLabels[headAimVector_?VectorQ,fixate_?VectorQ,distraction_?VectorQ,base_?VectorQ]:=
Show[{Graphics[{Magenta,{Text[StringForm["(Subscript[θ, r]) = `1`",Round[N[(180/π)rightθ[headAimVector,fixate,distraction,base]]]],rightEyeNode[headAimVector,fixate,base]-3eyeRadius(2rightEyeCenter[headAimVector,base]-distraction-fixate)/nORM[(2rightEyeCenter[headAimVector,base]-distraction-fixate)]]
,
Circle[rightEyeNode[headAimVector,fixate,base],2.25eyeRadius,Sort@{Min[rightδ[headAimVector,fixate,distraction,base],rightφ[headAimVector,fixate,base]],Max[rightδ[headAimVector,fixate,distraction,base],rightφ[headAimVector,fixate,base]]}]
}}],
Graphics[{Magenta,{Text[StringForm["(Subscript[θ, l]) = `1`",Round[N[(180/π)leftθ[headAimVector,fixate,distraction,base]]]],leftEyeNode[headAimVector,fixate,base]-3eyeRadius(2leftEyeCenter[headAimVector,base]-distraction-fixate)/nORM[(2leftEyeCenter[headAimVector,base]-distraction-fixate)]]
,
Circle[leftEyeNode[headAimVector,fixate,base],2.25eyeRadius,Sort@{Min[leftδ[headAimVector,fixate,distraction,base],leftφ[headAimVector,fixate,base]],Max[leftδ[headAimVector,fixate,distraction,base],leftφ[headAimVector,fixate,base]]}]
}}]
},AspectRatio->Automatic];
(*Real Program Starts Here*)
headAimVector[aim_]:={Sin[aim π/180],Cos[aim π/180]};
Quiet@Show[{
inRays[headAimVector[aim],fixate,distraction,base]
,
inLabels[headAimVector[aim],fixate,distraction,base]
,
outRays[headAimVector[aim],fixate,distraction,base]
,
outLabels[headAimVector[aim],fixate,distraction,base]
,
Graphics[{AbsolutePointSize[4],Point[midPoint[headAimVector[aim],base]]}]
,
Graphics[{Green,AbsolutePointSize[4],{Point[base]
,
Text["B",base-{0,.5}]
,
Point[headAimVector[aim]+base]
,
Text["A",1.05headAimVector[aim]+base+{0,.5}]
,
Text["A",1.05headAimVector[aim]+{0,.5}]
}}]
,
Graphics[{Red,AbsolutePointSize[4],{Point[fixate],Text["F",1.1fixate],Line[{leftEyeNode[headAimVector[aim],fixate,base],fixate}],Line[{rightEyeNode[headAimVector[aim],fixate,base],fixate}],
Circle[fixate,1,Sort@{leftφ[headAimVector[aim],fixate,base]+π,rightφ[headAimVector[aim],fixate,base]+π}]}}]
,
Graphics[{Blue,AbsolutePointSize[5],
{Point[distraction],
Text["D",1.05distraction],
Line[{leftEyeNode[headAimVector[aim],fixate,base],distraction}],Line[{rightEyeNode[headAimVector[aim],fixate,base],distraction}],Circle[distraction,1,Sort@{leftδ[headAimVector[aim],fixate, distraction,base]+π,rightδ[headAimVector[aim],fixate, distraction,base]+π}]}}]
},PlotRange->{{-9,9},{-3.5,15}},AspectRatio->Automatic,ImageSize->{400,400}]]
,
{{eyeRadius,1.3,"eye radius"},1,2,.01,ImageSize->Tiny,Appearance->"Labeled"},
{{interOcular,6.5,"interocular"},5,8,.01,ImageSize->Tiny,Appearance->"Labeled"},
{{aimOffset,.125,"aim offset"},-.5,.5,.01,ImageSize->Tiny,Appearance->"Labeled"},
{{nodePercent,.5,"node percent"},0,.75,.01,ImageSize->Tiny,Appearance->"Labeled"},
{{base,{0,0}},{-3,-2},{3,.5},Locator},
{{aim,0,"head aim"},-15,15,.01,ImageSize->Tiny,Appearance->"Labeled"},
{{fixate,{-1.6,10.43}},{-7,6},{7,13},Locator},
{{distraction,{2,13}},{-8,5},{8,14},Locator},ControlPlacement->Left]

CAPTION

This Demonstration allows you to manipulate several eye parameters: eye radius, interocular distance, and offset in a model of the horizontal fixation plane of the eyes "fixed" on the point F and also observing the distractor D. The scale is very small to exaggerate the angles in order to see what they measure at normal viewing distances.

The angles (Subscript[θ, l]) and (Subscript[θ, r]) for the left and right eyes are measured counterclockwise from the line to the distractor to the line to the fixate, shown in degrees. The difference between these angles is the important "binocular disparity" used in static visual depth perception and described in the Demonstration "Binocular Disparity (Visual Depth Perception 7)" (see Related Links).

The node points of the eyes, shown as green dots in the eyes, are at the location of the effective "pinhole lens" created by a combination of the focal properties of the cornea and the eye's lens. The location of the node point determines the relation between the internal and external angles (Subscript[θ, l]) and (Subscript[θ, l]^i), and (Subscript[θ, r]) and (Subscript[θ, r]^i) for this simple model that assumes the cross sections of the eyes are circles. On the slider, this location is given as a fraction of the radius of the eye. When the node percent is zero the internal and external angles are equal, but a more typical physiological approximation would be a node percent equal to 1/2.

The other sliders are self-explanatory: if you move them, you will see what they do.

DETAILS

This collection of Demonstrations is mainly concerned with describing the geometric inputs to vision that are needed for both static and moving depth perception. There is an outline in the Demonstration "Motion/Pursuit Law in 1D (Visual Depth Perception 1)" (see Related Links).

THIS NOTEBOOK IS THE SOURCE CODE FROM

"Eye Parameters (Visual Depth Perception 6)" from the Wolfram Demonstrations Project
 http://demonstrations.wolfram.com/EyeParametersVisualDepthPerception6/

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 »