Skip to content

Commit

Permalink
Infinity curvature support
Browse files Browse the repository at this point in the history
  • Loading branch information
monman53 committed Jul 5, 2024
1 parent fd6b81d commit 5a30723
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 32 deletions.
51 changes: 46 additions & 5 deletions src/Controller.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<script setup lang="ts">
import { computed } from 'vue'
import { state, lensGroups, defaultConvexLens, defaultConcaveLens, sensor, appleProps, options, style, defaultDoubletLens, lights } from './globals'
import { state, lensGroups, defaultConvexLens, defaultConcaveLens, sensor, appleProps, options, style, defaultDoubletLens, lights, globalLensInfo } from './globals'
import { humanReadable } from './utils';
import { Light } from "./type"
import { Light, type Lens, type LensPlane } from "./type"
import { lenses } from './collection/lense';
const nRays = computed(() => {
return 1 << state.value.nRaysLog
Expand All @@ -17,6 +18,38 @@ const createSensor = (d: number) => {
sensor.value.t.y = d / 2
}
const setLens = (lens: any) => {
const nPlanes: LensPlane[] = []
let x = 0
let n = 1
lens.planes.forEach((plane: any) => {
nPlanes.push({
x: x,
r: plane.r,
h: plane.h,
na: n,
nb: plane.n
})
x += plane.d
n = plane.n
})
lensGroups.value = []
for(let i=0;i<nPlanes.length;i+=2){
lensGroups.value.push({
lenses: [
{
planes: [
nPlanes[i],
nPlanes[i+1],
],
aperture: 1,
}
],
selected: false,
})
}
}
</script>

<template>
Expand Down Expand Up @@ -134,12 +167,12 @@ const createSensor = (d: number) => {
<td>{{ humanReadable(lens.n) }}</td>
</tr> -->
</template>
<!-- <tr>
<tr>
<td>Focal Length</td>
<td></td>
<td>{{ humanReadable(lens.f) }}</td>
<td>{{ humanReadable(globalLensInfo.f) }}</td>
</tr>
<tr>
<!-- <tr>
<td>F-number</td>
<td></td>
<td>{{ humanReadable(fNumber) }}</td>
Expand Down Expand Up @@ -287,6 +320,14 @@ const createSensor = (d: number) => {
</td>
<td></td>
</tr> -->
<tr>
<td>Lens collection</td>
<td>
<template v-for="lens of lenses">
<button @click="setLens(lens)">{{ lens.name }}</button>
</template>
</td>
</tr>
<tr>
<td>Sensor height</td>
<td>
Expand Down
18 changes: 15 additions & 3 deletions src/SVG/Lens.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,21 @@ const path = computed(() => {
// left
d += `M ${edge1} ${-r.value} `
d += `L ${edge1} ${-p1.h} `
d += `A ${absR1} ${absR1} 0 0 ${sweep1} ${edge1} ${p1.h} `
if (isFinite(p1.r)) {
d += `A ${absR1} ${absR1} 0 0 ${sweep1} ${edge1} ${p1.h} `
} else {
d += `L ${edge1} ${p1.h} `
}
d += `L ${edge1} ${r.value} `
// right
d += `L ${edge2} ${r.value} `
d += `L ${edge2} ${p2.h} `
d += `A ${absR2} ${absR2} 0 0 ${sweep2} ${edge2} ${-p2.h} `
if (isFinite(p2.r)) {
d += `A ${absR2} ${absR2} 0 0 ${sweep2} ${edge2} ${-p2.h} `
} else {
d += `L ${edge2} ${-p2.h} `
}
d += `L ${edge2} ${-r.value} `
// Close
Expand All @@ -62,7 +70,11 @@ const paths = computed(() => {
let d = ""
d += `M ${edge} ${-r.value} L ${edge} ${-p.h} `
d += `A ${absR} ${absR} 0 0 ${sweep} ${edge} ${p.h} `
if (isFinite(p.r)) {
d += `A ${absR} ${absR} 0 0 ${sweep} ${edge} ${p.h} `
} else {
d += `L ${edge} ${p.h}`
}
d += `L ${edge} ${r.value}`
return d
})
Expand Down
30 changes: 30 additions & 0 deletions src/collection/lense.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export const lenses = [
{
name: 'Rico 9mm-18mm',
url: 'https://www.j-platpat.inpit.go.jp/c1801/PU/JP-S46-019818/12/ja',
planes: [
// Afocal
{r: 44.58, d: 4.5, n: 1.58913, vd: 61.2, h: 16},
{r: Infinity, d: 3.7, n: 1.0, vd: null, h: 16},

{r: Infinity, d: 1.2, n: 1.62374, vd: 47.0, h: 10},
{r: 15.49, d: 24.3, n: 1.0, vd: null, h: 10},

{r: 40.62, d: 2.4, n: 1.58913, vd: 61.2, h: 8},
{r: -40.62, d: 1.2, n: 1, vd: null, h: 8},

{r: Infinity, d: 0.9, n: 1.62374, vd: 47.0, h: 4},
{r: 44.58, d: 5.0, n: 1, vd: null, h: 4},

// Relay
{r: 6.9, d: 2.0, n: 1.744, vd: 44.9, h: 4},
{r: -153, d: 0.9, n: 1, vd: null, h: 4},

{r: -12.9, d: 1.4, n: 1.69895, vd: 30.1, h: 4},
{r: 5.7, d: 1.5, n: 1, vd: null, h: 3},

{r: 13.6, d: 2.4, n: 1.713, vd: 53.9, h: 4},
{r: -9.1, d: Infinity, n: 1, vd: null, h: 4},
]
}
]
19 changes: 11 additions & 8 deletions src/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,17 +433,20 @@ export const calcLensInfo = (lenses: Lens[]) => {

const ls: number[] = []
const lss: number[] = []
let f = 1
let f = Infinity
ll.forEach((l, i) => {
if (i === 0) {
//ls[i] = Infinity
// lss[i] = 1 / (l.n / l.nn / ls[i] + 1 / l.r * (1 - l.n / l.nn))
lss[i] = 1 / (1 / l.r * (1 - l.na / l.nb))
f *= lss[i]
ls.push(Infinity)
lss.push(1 / (1 / l.r * (1 - l.na / l.nb)))
f = lss[i]
} else {
ls[i] = lss[i - 1] - ll[i - 1].d
lss[i] = 1 / (l.na / l.nb / ls[i] + 1 / l.r * (1 - l.na / l.nb))
f *= lss[i] / ls[i]
ls.push(lss[i - 1] - ll[i - 1].d)
lss.push(1 / (l.na / l.nb / ls[i] + 1 / l.r * (1 - l.na / l.nb)))
if (isFinite(f)) {
f *= lss[i] / ls[i]
} else {
f = lss[i]
}
}
})
let H = 0
Expand Down
3 changes: 3 additions & 0 deletions src/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,9 @@ export const calcLensPlaneEdge = (plane: LensPlane) => {
const x = plane.x
const r = plane.r
const h = plane.h
if (!isFinite(r)) {
return x
}
const d = Math.abs(r) - Math.sqrt(r * r - h * h)
if (r > 0) {
return x + d
Expand Down
64 changes: 48 additions & 16 deletions src/rayTrace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,67 @@ import type { Ray } from "./type";

type CollisionResult = ({ p: Vec, d: number, isSensor?: boolean, isEnd?: boolean, vn?: () => Vec } | null)

const collisionLens = (rays: Ray[], cx: number, r: number, h: number, ni: number, no: number): CollisionResult[] => {
const collisionLens = (rays: Ray[], x: number, r: number, h: number, ni: number, no: number): CollisionResult[] => {
return rays.map(ray => {
let v = ray.v
let s = ray.s
v = v.normalize()
const pls = intersectionCL(cx, r, s, v)
if (pls.length === 0) {
return null
}
for (const pl of pls) {
// TODO: Find better condition
const collision = (r > 0 ? pl.p.x < cx : pl.p.x > cx) && Math.abs(pl.p.y) < h
if (collision) {
if (isFinite(r)) {
const cx = x + r
const pls = intersectionCL(cx, r, s, v)
if (pls.length === 0) {
return null
}
for (const pl of pls) {
// TODO: Find better condition
const collision = (r > 0 ? pl.p.x < cx : pl.p.x > cx) && Math.abs(pl.p.y) < h
if (collision) {
return {
p: pl.p,
d: pl.d,
vn: () => {
const n = vec(pl.p.x - cx, pl.p.y)
if (dot(n, v) < 0) {
// Outside to inside
const phi1 = crossAngle(v, n)
const phi2 = Math.asin(Math.sin(phi1) * no / ni)
const theta = Math.atan2(n.y, n.x) + phi2 + Math.PI
return vecRad(theta)
} else {
// Inside to outside
const phi1 = crossAngle(v.minus(), n)
const phi2 = Math.asin(Math.sin(phi1) * ni / no)
const theta = Math.atan2(n.y, n.x) + phi2
return vecRad(theta)
}
}
}
}
}
} else {
const pl = intersectionY(s, v, x, -h, h)
if (pl.p !== null) {
return {
p: pl.p,
d: pl.d,
vn: () => {
const n = vec(pl.p.x - cx, pl.p.y)
// const n = vec(Infinity, 0)
const n = vec(-Math.sign(r), 0)
if (dot(n, v) < 0) {
// Outside to inside
const phi1 = crossAngle(v, n)
const phi2 = Math.asin(Math.sin(phi1) * no / ni)
const theta = Math.atan2(n.y, n.x) + phi2 + Math.PI
let theta = Math.asin(Math.sin(phi1) * no / ni) + Math.PI
if (r === Infinity) {
theta += Math.PI
}
return vecRad(theta)
} else {
// Inside to outside
const phi1 = crossAngle(v.minus(), n)
const phi2 = Math.asin(Math.sin(phi1) * ni / no)
const theta = Math.atan2(n.y, n.x) + phi2
let theta = Math.asin(Math.sin(phi1) * ni / no)
if (r === Infinity) {
theta += Math.PI
}
return vecRad(theta)
}
}
Expand Down Expand Up @@ -192,7 +224,7 @@ const collisionAll = (rays: Ray[]): CollisionResult[] => {
const ni = p.r > 0 ? p.nb : p.na
const no = p.r > 0 ? p.na : p.nb
// Plane
updateMin(collisionLens(rays, p.x + p.r, p.r, p.h, ni, no))
updateMin(collisionLens(rays, p.x, p.r, p.h, ni, no))

// Plane outside
updateMin(collisionAperture(rays, lensPlaneEdges.value[i][j], p.h, h))
Expand Down Expand Up @@ -241,7 +273,7 @@ export const rayTrace = (rays: Ray[]): Segment[][] => {
const s = ray.s
const c = cs[idx]
if (c === null) {
segments[ray.idx].push({ s, t: ray.s.add(ray.v.mul(infR.value))})
segments[ray.idx].push({ s, t: ray.s.add(ray.v.mul(infR.value)) })
return
}

Expand Down

0 comments on commit 5a30723

Please sign in to comment.