Got real tracing, seidel calulations working

This commit is contained in:
2022-10-07 23:35:40 +02:00
parent 11cd3ee503
commit a84bade226
4 changed files with 149 additions and 24 deletions

View File

@@ -1,9 +1,8 @@
-- | General utilities for dealing with full lens systems (i.e., the composition of multiple refracting surfaces)
module Petzval.System
( Pupil(..)
, entrancePupil
, createRay
, seidel, Seidel(..)
, Ray
) where
import Petzval.Optics
@@ -15,7 +14,6 @@ import Data.List
import qualified Debug.Trace
data Ray a = Ray (V3 a) (V3 a)
splitSystem :: [ Element mat a ] -> ([Element mat a], Maybe (Element mat a), [Element mat a])
splitSystem (s@Stop{}:rest) = ([], Just s, rest)
@@ -23,6 +21,7 @@ splitSystem [] = ([], Nothing, [])
splitSystem (s:rest) = (s:pfx, stop, sfx)
where (pfx, stop, sfx) = splitSystem rest
-- | A pupil (real or virtual, entrance or exit)
data Pupil a = Pupil { radius :: a, position :: a }
deriving (Show)
@@ -33,24 +32,13 @@ pupil (stop@Stop{_outsideRadius}) subsystem =
--msg = intercalate " " ["ptrace: ", show (rtm !* V2 (_outsideRadius / my ) 0)]
in Pupil { radius = _outsideRadius / my
, position = -cy / cu }
-- | Compute the entrance pupil of a system viewed from infinity
entrancePupil :: (RealFloat a, Mode a, Scalar a ~ Double, Epsilon a, Show a) => [Element BakedIOR a] -> Pupil a
entrancePupil system = pupil stop prefix
where (prefix, (Just stop), _) = splitSystem system
createRay :: (RealFloat a, Mode a, Scalar a ~ Double, Epsilon a) => Maybe a -> Pupil a -> a -> (a,a) -> Ray a
createRay (Just objectPlane) Pupil{position=pz,radius=pr} h (px, py) =
Ray source (normalize $ target ^-^ source)
where dz = pz - objectPlane
source = V3 0 (dz * tan h) objectPlane
target = V3 (px * pr) (py * pr) pz
createRay Nothing Pupil{position=pz,radius=pr} h (px, py) = Ray source (normalize $ target ^-^ source)
where h' = (pi * (-abs h) / 180) -- field angle in rad
dy = (V3 0 (cos h') (-sin h')) `project` (V3 0 (py * pr) 0)
dz = V3 0 (pz * tan h') (pz * cos h')
source = dy ^+^ dz
target = V3 (px * pr) (py * pr) pz
-- | The set of seidel coefficients of a lens system
data Seidel a = Seidel
{ sphr, coma, asti, fcur, dist :: a
-- , c1, c2 :: a
@@ -114,9 +102,7 @@ seidel' rays (s@Surface{_material=BakedIOR n1 n2,_roc=roc}) = Debug.Trace.trace
-- cbas = h (n2 - n1) / n1
-- c1 =
-- | Compute the seidel coefficients of a system given the pupil and field angle
seidel :: (RealFloat a, Mode a, Scalar a ~ Double, Epsilon a, Show a) => Pupil a -> Double -> [Element BakedIOR a] -> [Seidel a]
seidel pupil fieldAngle =
snd . mapAccumL seidel' rays