| NA's profileqBSMDPhotosBlogNetwork | Help |
|
|
July 02 continuation of eye evolutionfunction [score,out]=visiontest(layer) %Like the eye doctor for a brainless, computer generated eye. [nm,nn,nl]=size(layer); %xx=reshape(layer(:,2,:),nm,nl); %Calculate x and y coordinates %yy=reshape(layer(:,3,:),nm,nl); %for eye for display. raymult=10; numpos=nm; %Number of angles at which to test vision. r=10*max(max(layer(end,2:3,:))); %Calculate safe distance (not inside eye). rayth=atan2(layer(nm,2,nl)-0 ,r-layer(nm,3,nl));%Calc angle from center to outside of outer layer. for ii=1:numpos %hold off;plot(xx,yy,'.-');axis([-r/10,r/5,-r/10,r/5]);hold on; theta=pi/2/numpos*(ii-1); %Put object at angles as measured x=r*sin(theta); y=r*cos(theta)+max(max(layer(:,3,:)));%clockwise from straight ahead. out(:,ii)=retina(layer,x,y,raymult,rayth);%Get output on retina from source @ (x,y). %pause(.3); end ret=sum(sum(out')~=0); %Number of used retinal cells s=sqrt(sum(out.^2)); %Magnitude of retinal response at each angle f=find(s~=0); %Angles for which response exists (in fov) fov=length(f); %Number of angles inside field of view focus=mean(sum(out(:,f)~=0))/fov; %Mean number of retinal cells responding at each angle lightr=mean(max(out(:,f)))/raymult/nm/numpos;%Intensity of image seen, % of light recieved/light sent %tst=out(:,f)'*out(:,f)./(s(f)'*s(f)); %Cosine of angles between retinal activation patterns: %percept=sum(sum((eye(length(f))-tst).^2)); %Linear independance of patterns from each source angle %complex=1+nm*nl/1000; %Punishes unecessary complexity %light=sum(sum(out))/raymult/nm/numpos; % % of light hitting retina score=(nm-ret)/ret+focus/lightr; %Fitness measure (lower=better) %[focus,ret,light,score] %wants exactly one retinal cell to %respond strongly for each angle, %i.e. a bright, focused image. function out=retina(layer,x,y,raymult,rayth) %monte carlo method; generates nm random rays from point (x,y) and counts hits on retina [nm,nn,nl]=size(layer); out=zeros(nm,1); thl=atan2(layer(1,2,nl)-x ,y-layer(1,3,nl));%Calc angle to center of outer layer. thr=atan2(layer(nm,2,nl)-x,y-layer(nm,3,nl));%Calc angle to extreme of outer layer. thcen=(thl+thr)/2; %Calc angle to center. thl=thcen-rayth; thr=thcen+rayth; %Reset to consistant boundaries. for ii=1:raymult*nm %Proportionally to resolution of retina, theta=(thr-thl)*rand+thl; %generate random ray hitting epithelium of eye. rout=raytrace(layer,x,y,theta); %Run raytracer below, and if rout(1)~=0 %if ray hits retina, out(rout(1))=out(rout(1))+rout(2); %add result to correct retinal cells. out(rout(1)+1)=out(rout(1)+1)+1-rout(2); end end function out=raytrace(layer,x,y,th) %uses linear interpolation of properties specified in "layer" to track light ray % from x,y @ angle th to retina of eye %angle is measured from down, positive to the right [nm,nn,nl]=size(layer); out=[0,0,0]; %Zero output flag. for ll=nl:-1:1 %Loop over all layers: %xold=x; yold=y; thhit=[0,0,1000000]; %Initialize variable to store segment. for mm=1:nm %Loop over all segments: thtest=atan2(layer(mm,2,ll)-x,y-layer(mm,3,ll));%Calculate angle from source to current cell. d=(layer(mm,2,ll)-x)^2+(layer(mm,3,ll)-y)^2; %Calculate distance to current cell. if mm~=1&&d<thhit(3)&&thold(1)<=th&&th<thtest %If ray hits this segment, and is closer thhit=[thold(1:2),d]; %than last hit segment, remember this. end thold=[thtest,mm,d]; %Right bound becomes left bound of next segment. end if thhit(2)==0 %If no segment is hit, return; %no retinal response. end xl=layer(thhit(2),2,ll); xr=layer(thhit(2)+1,2,ll); %Get left and right yl=layer(thhit(2),3,ll); yr=layer(thhit(2)+1,3,ll); %coords of segment x0=x; y0=y; %and source. cth=cot(th); %Calculate slope from source to layer, x=((xl-xr)*y0+xr*yl-xl*yr+x0*xl*cth-x0*xr*cth)/... (yl-yr+(xl-xr)*cth); %then calculate x and y coords of y=(y0*(yl-yr)+(xl*yr-xr*yl+x0*(yl-yr))*cth)/... (yl-yr+(xl-xr)*cth); %intersection of ray with layer. q=norm([xl,yl]-[x,y])/norm([xl,yl]-[xr,yr]); %Calc % of direction from left cell to interpolate properties. segang=atan2(yr-yl,xr-xl); %Calculate angle of segment hit by ray. th=th-segang; %Snell's law requires angle of ray relative to segment. if ll==nl %Calculate index of refraction before transition, n1=1; %assuming that n=1 for environment, else n1=q*layer(thhit(2),1,ll+1)+(1-q)*layer(thhit(2)+1,1,ll+1);%and n for anything else is specified. end %plot([xold;x],[yold,y]); %Display rays (not recommended except for making graphics for presentations). if ll~=1 %If not on retina, n2=q*layer(thhit(2),1,ll)+(1-q)*layer(thhit(2)+1,1,ll);%calculate index of refraction after transition, th=asin(sin(th)*n1/n2); %and angle of refraction from Snell's Law: %n=c/vp, sin(th1)/sin(th2)=v1/v2=n2/n1 if imag(th)~=0 %If total internal reflection, %plot(x,y,'rx'); return; %(past critical angle) ignore ray. end th=th+segang; %Get angle relative to absolute coordinate frame. end end out=[thhit(2),q,d]; %Return index of retinal cell left of where ray hit, and interpolation value. TrackbacksThe trackback URL for this entry is: http://qbsmd.spaces.live.com/blog/cns!5BA0601679A003C2!118.trak Weblogs that reference this entry
|
|
|