Skip to content
This repository has been archived by the owner on Oct 23, 2022. It is now read-only.

Commit

Permalink
Cluser size and eyebox subdivision can be out of sync (#381)
Browse files Browse the repository at this point in the history
Fixes #380

modified setup_nominal_system,setup_system, and choosecluster to take a no_eyebox_subdivision keyword argument. Ensured cluster data and eyebox subdivisions are consistent.
  • Loading branch information
BrianGun authored Mar 11, 2022
1 parent 768ddf2 commit 45017e6
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 20 deletions.
29 changes: 15 additions & 14 deletions src/RepeatingStructures/Multilens/Analysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,14 @@ closestpackingdistance(pupildiameter::Unitful.Length) = pupildiameter * cosd(30)
export closestpackingdistance

"""Tries clusters of various sizes to choose the largest one which fits within the eye pupil. Larger clusters allow for greater reduction of the fov each lenslet must cover so it returns the largest feasible cluster"""
function choosecluster(pupildiameter::Unitful.Length, lensletdiameter::Unitful.Length)
function choosecluster(pupildiameter::Unitful.Length, lensletdiameter::Unitful.Length, no_eyebox_subdivision::Bool = false)
#for now don't use cluster sizes that are not divisible by 3 since this causes problems with RGB subdivision of the lenslets. Maybe add back in later.
# clusters = (hex3RGB, hex4RGB, hex7RGB , hex9RGB, hex12RGB,hex19RGB) #, hex37RGB) # hex37RGB leave out for now. Leads to designs with thousands of small lenslets. May not be practical.
clusters = (hex3RGB, hex9RGB, hex12RGB,hex18RGB) #, hex37RGB) # hex37RGB leave out for now. Leads to designs with thousands of small lenslets. May not be practical.
# clusters = (hex3RGB, hex4RGB, hex7RGB , hex9RGB, hex12RGB,hex19RGB) #, hex37RGB) # hex37RGB leave out for now. Leads to designs with thousands of small lenslets. May not be practical.
if no_eyebox_subdivision
clusters = (hex3RGB,)
else
clusters = (hex3RGB, hex9RGB, hex12RGB,hex18RGB) #, hex37RGB) # hex37RGB leave out for now. Leads to designs with thousands of small lenslets. May not be practical.
end
pupildiameter
ratio = 0.0
clusterindex = 0
Expand Down Expand Up @@ -163,9 +167,9 @@ end
export choosecluster

"""Computes the largest feasible cluster size meeting constraints"""
function choosecluster(pupildiameter::Unitful.Length, λ::Unitful.Length, mtf, cyclesperdeg::T) where {T <: Real}
function choosecluster(pupildiameter::Unitful.Length, λ::Unitful.Length, mtf, cyclesperdeg::T, no_eyebox_subdivisions::Bool = false) where {T <: Real}
diam = diameter_for_cycles_deg(mtf, cyclesperdeg, λ)
return choosecluster(pupildiameter, diam) # use minimum diameter for now.
return choosecluster(pupildiameter, diam, no_eyebox_subdivisions) # use minimum diameter for now.
end

"""This computes the approximate size of the entire display, not the individual lenslet displays."""
Expand All @@ -185,8 +189,7 @@ eyeboxangles(eyebox,eyerelief) = @. atand(uconvert(Unitful.NoUnits, eyebox / eye
export eyeboxangles

"""This code is tightly linked to the cluster sizes returned by choosecluster. This is not goood design to link these two functions. Think about how to decouple these two functions. computes how the fov can be subdivided among lenslets based on cluster size. Assumes the horizontal size of the eyebox is larger than the vertical so the larger number of subdivisions will always be the first number in the returns Tuple."""
function anglesubdivisions(pupildiameter::Unitful.Length, λ::Unitful.Length, mtf, cyclesperdegree;RGB=true)
cluster, _ = choosecluster(pupildiameter, λ, mtf, cyclesperdegree)
function anglesubdivisions(cluster, pupildiameter::Unitful.Length, λ::Unitful.Length, mtf, cyclesperdegree;RGB=true)
numelements = Repeat.clustersize(cluster)
if numelements == 37
return RGB ? (4,3) : (6,6)
Expand Down Expand Up @@ -262,16 +265,14 @@ Dict{Symbol, Any} with 14 entries:
```
"""
function system_properties(eyerelief::Unitful.Length, eyebox::NTuple{2,Unitful.Length}, fov, pupildiameter::Unitful.Length, mtf, cyclesperdegree; minfnumber=2.0,RGB=true=530nm,pixelpitch=.9μm, maxdisplaysize = 250μm,eyebox_subdivisions::Union{Nothing,Tuple{Int,Int}} = nothing)::Dict{Symbol,Any}
function system_properties(eyerelief::Unitful.Length, eyebox::NTuple{2,Unitful.Length}, fov, pupildiameter::Unitful.Length, mtf, cyclesperdegree; minfnumber=2.0,RGB=true=530nm,pixelpitch=.9μm, maxdisplaysize = 250μm, no_eyebox_subdivision::Bool = false)::Dict{Symbol,Any}
diameter = diameter_for_cycles_deg(mtf, cyclesperdegree, λ)
clusterdata = choosecluster(pupildiameter, diameter)
clusterdata = choosecluster(pupildiameter, diameter,no_eyebox_subdivision)
difflimit = diffractionlimit(λ, clusterdata.lensletdiameter)
numlenses = numberoflenslets(fov, eyerelief, clusterdata.lensletdiameter)
if eyebox_subdivisions === nothing
subdivisions = anglesubdivisions(pupildiameter, λ, mtf, cyclesperdegree, RGB=RGB)
else
subdivisions = eyebox_subdivisions
end

subdivisions = anglesubdivisions(clusterdata.cluster, pupildiameter, λ, mtf, cyclesperdegree, RGB=RGB)

eyebox_angles = eyeboxangles(eyebox,eyerelief)
angles = eyebox_angles ./ subdivisions
redundancy = pixelredundancy(fov, eyerelief, eyebox, pupildiameter,clusterdata.lensletdiameter, angles, RGB=RGB)
Expand Down
6 changes: 3 additions & 3 deletions src/RepeatingStructures/Multilens/Example.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


""" Typical properties for near eye VR display """
nominal_system_inputs() = (eye_relief = 20mm, fov = (5°,5°),eyebox = (10mm,8mm),display_radius = 125.0mm, pupil_diameter = 3.5mm,pixel_pitch = .9μm, minfnumber = 2.0, mtf = .2, cycles_per_degree = 11, max_display_size = 250μm, )
nominal_system_inputs() = (eye_relief = 20mm, fov = (20°,20°),eyebox = (10mm,8mm),display_radius = 125.0mm, pupil_diameter = 3.5mm,pixel_pitch = .9μm, minfnumber = 2.0, mtf = .2, cycles_per_degree = 11, max_display_size = 250μm, )
export nominal_system_inputs

xcoords(a::SMatrix{3,4}) = a[1,:]
Expand Down Expand Up @@ -52,9 +52,9 @@ end
export test_paraxial_lens

"""Example that shows how to call setup_system with typical values"""
function setup_nominal_system(;eyebox_subdivisions = nothing)::LensletSystem
function setup_nominal_system(;no_eyebox_subdivision::Bool = false)::LensletSystem
(;eye_relief,fov,eyebox,display_radius,pupil_diameter,minfnumber,pixel_pitch) = nominal_system_inputs()
setup_system(eyebox,fov,eye_relief,pupil_diameter,display_radius,minfnumber,pixel_pitch,eyebox_subdivisions = eyebox_subdivisions)
setup_system(eyebox,fov,eye_relief,pupil_diameter,display_radius,minfnumber,pixel_pitch,no_eyebox_subdivision = no_eyebox_subdivision)
end
export setup_nominal_system

Expand Down
6 changes: 3 additions & 3 deletions src/RepeatingStructures/Multilens/LensletAssignment.jl
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ If you do this
setup_system(eye_box,(1,1.2),...)
```
the system will assume the angle is in radians."""
function setup_system(eye_box,fov,eye_relief,pupil_diameter,display_sphere_radius,min_fnumber,pixel_pitch;eyebox_subdivisions = nothing)
function setup_system(eye_box,fov,eye_relief,pupil_diameter,display_sphere_radius,min_fnumber,pixel_pitch;no_eyebox_subdivision::Bool = false)
#All coordinates are ultimately transformed into the eyeball_frame coordinate systems
(eyeball_frame,eye_box_frame) = setup_coordinate_frames()

Expand All @@ -264,7 +264,7 @@ function setup_system(eye_box,fov,eye_relief,pupil_diameter,display_sphere_radiu
eyeboxz = (eye_box_frame*SVector(0.0,0.0,0.0))[3]
eyebox_plane = Plane([0.0,0.0,1.0],[0.0,0.0,eyeboxz])
#get system properties
props = system_properties(eye_relief,eye_box,fov,pupil_diameter,.2,11,pixelpitch = pixel_pitch, minfnumber = min_fnumber,eyebox_subdivisions = eyebox_subdivisions)
props = system_properties(eye_relief,eye_box,fov,pupil_diameter,.2,11,pixelpitch = pixel_pitch, minfnumber = min_fnumber,no_eyebox_subdivision = no_eyebox_subdivision)

subdivisions = props[:subdivisions] #tuple representing how the eyebox can be subdivided given the cluster used for the lenslets

Expand Down Expand Up @@ -303,7 +303,7 @@ function setup_system(eye_box,fov,eye_relief,pupil_diameter,display_sphere_radiu
projected = project_eyebox_to_display_plane.(lenslet_eye_boxes,offset_lenses,displayplanes) #repeate subdivided_eyeboxpolys enough times to cover all lenses
projected_eyeboxes = [x[1] for x in projected]
projected_polygons = [x[2] for x in projected]
@info "typeof polygon $(eltype(projected_polygons))"
@info "Lenslet diameter $(props[:lenslet_diameter])"

eyebox_rectangle = Rectangle(ustrip(mm,eye_box[1]/2),ustrip(mm,eye_box[2]/2),[0.0,0.0,1.0],[0.0,0.0,eyeboxz], interface = opaqueinterface())

Expand Down

0 comments on commit 45017e6

Please sign in to comment.