Skip to content

Commit

Permalink
Minor change
Browse files Browse the repository at this point in the history
  • Loading branch information
monman53 committed Jun 14, 2024
1 parent 1cf7a8b commit 050ca5b
Show file tree
Hide file tree
Showing 6 changed files with 359 additions and 349 deletions.
226 changes: 226 additions & 0 deletions src/Controller.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
<script setup lang="ts">
import { computed } from 'vue'
import { state, lens, sensor, options, style, lensD, lensR, fNumber } from './globals'
import { humanReadable } from './utils';
const nRays = computed(() => {
return 1 << state.value.nRaysLog
})
</script>

<template>
<table>
<!-- Rays -->
<tr>
<th colspan="3">Lights</th>
</tr>
<tr>
<td># of rays</td>
<td><input type="range" min="0" max="16" v-model.number="state.nRaysLog"></td>
<td>{{ nRays }}</td>
</tr>
<tr>
<td>Intensity</td>
<td><input type="range" min="0" max="1" step="0.001" v-model.number="style.rayIntensity"></td>
<td>{{ humanReadable(style.rayIntensity) }}</td>
</tr>
<tr>
<td>Ray thickness</td>
<td><input type="range" min="0.01" max="1" step="0.001" v-model.number="style.rayWidth"></td>
<td>{{ humanReadable(style.rayWidth) }}</td>
</tr>
<tr>
<td>New light color</td>
<td>
<input type="range" min="0" max="360" step="0.001" v-model="state.newLightColor">
<br>
<button @click="state.newLightColor = 0">Red</button>
<button @click="state.newLightColor = 120">Green</button>
<button @click="state.newLightColor = 240">Blue</button>
</td>
<td :style="`background-color: hsl(${state.newLightColor}, 100%, 50%)`"></td>
</tr>
<!-- Lens -->
<tr>
<th colspan="3">
<hr><label><input type="checkbox" v-model="options.lens"> Lens</label>
</th>
</tr>
<template v-if="options.lens">
<tr>
<td><label><input type="checkbox" v-model="options.lensFocalPoints"> Focal points</label>
</td>
</tr>
<tr v-if="options.lensFocalPoints && options.advanced">
<td><label><input type="checkbox" v-model="options.lensDoubleFocalPoints"> 2x Focal
points</label>
</td>
</tr>
</template>
<tr>
<td><label><input type="checkbox" v-model="options.aperture"> Aperture</label></td>
</tr>
<template v-if="options.lens">
<template v-if="options.advanced">
<tr>
<td><label><input type="checkbox" v-model="options.curvature"> Curvature</label></td>
<td></td>
<td>{{ humanReadable(lensR) }}</td>
</tr>
<tr>
<td><label><input type="checkbox" v-model="options.lensIdeal"> Ideal lens</label></td>
</tr>
<tr>
<td>Refractive index</td>
<td><input type="range" min="1.01" max="3" step="0.001" v-model.number="lens.n"></td>
<td>{{ humanReadable(lens.n) }}</td>
</tr>
</template>
<tr>
<td>Focal Length</td>
<td></td>
<td>{{ humanReadable(lens.f) }}</td>
</tr>
<tr>
<td>F-number</td>
<td></td>
<td>{{ humanReadable(fNumber) }}</td>
</tr>
<template v-if="options.advanced">
<tr>
<td>Position</td>
<td></td>
<td>{{ humanReadable(lens.x) }}</td>
</tr>
<tr>
<td>Diameter</td>
<td></td>
<td>{{ humanReadable(lens.r * 2) }}</td>
</tr>
<tr>
<td>Thickness</td>
<td></td>
<td>{{ humanReadable(lensD) }}</td>
</tr>
</template>
</template>
<!-- Screen -->
<tr>
<th colspan="3">
<hr><label><input type="checkbox" v-model="options.sensor"> Screen</label>
</th>
</tr>
<template v-if="options.sensor">
<tr>
<td><label><input type="checkbox" v-model="options.sensorPreview"> Preview</label></td>
</tr>
<!-- <tr v-if="options.sensorPreview">
<td><label><input type="checkbox" v-model="options.sensorMemory"> Memory</label></td>
</tr> -->
<template v-if="options.advanced">
<tr>
<td><label><input type="checkbox" v-model="options.circleOfConfusion"> CoC</label></td>
<template v-if="options.circleOfConfusion">
<td><input type="range" min="0" max="10" step="0.001" v-model.number="lens.circleOfConfusion">
</td>
<td>{{ humanReadable(lens.circleOfConfusion) }}</td>
</template>
</tr>
<tr>
<td>Diameter</td>
<td></td>
<td>{{ humanReadable(sensor.r * 2) }}<br></td>
</tr>
</template>
</template>
<!-- Other options -->
<tr>
<th colspan="3">
<hr>Other Options
</th>
</tr>
<tr>
<td><label><input type="checkbox" v-model="options.body"> Wall</label></td>
</tr>
<tr v-if="options.lens && options.sensor">
<td><label><input type="checkbox" v-model="options.angleOfView"> Guide lines</label></td>
</tr>
<tr>
<td><label><input type="checkbox" v-model="options.advanced"> Advanced mode</label></td>
</tr>
<template v-if="options.advanced">
<tr v-if="options.lens && options.sensor && options.circleOfConfusion">
<td><label><input type="checkbox" v-model="options.depthOfField"> Depth of field</label>
</td>
</tr>
<tr v-if="options.lens && options.sensor && options.circleOfConfusion && options.depthOfField">
<td><label><input type="checkbox" v-model="options.hyperfocalPoint"> Hyperfocal
point</label>
</td>
</tr>
<tr>
<td><label><input type="checkbox" v-model="options.grid"> Grid</label></td>
</tr>
<tr>
<td><label><input type="checkbox" v-model="options.opticalAxis"> Optical axis</label></td>
</tr>
</template>
<!-- Field -->
<template v-if="options.advanced">
<tr>
<th colspan="3">
<hr>Field
</th>
</tr>
<tr>
<td>Width</td>
<td></td>
<td>{{ humanReadable(state.width) }}</td>
</tr>
<tr>
<td>Height</td>
<td></td>
<td>{{ humanReadable(state.height) }}</td>
</tr>
<tr>
<td>Center x</td>
<td></td>
<td>{{ humanReadable(state.cx) }}</td>
</tr>
<tr>
<td>Center y</td>
<td></td>
<td>{{ humanReadable(state.cy) }}</td>
</tr>
<tr>
<td>Scale</td>
<td></td>
<td>{{ humanReadable(state.scale) }}</td>
</tr>
</template>
</table>
</template>

<style scoped>
.indent {
padding-left: 1em;
}
table td {
vertical-align: top;
}
table td:nth-child(1) {
padding-left: 1em;
text-align: left;
}
table td:nth-child(2) {
text-align: right;
}
table td:nth-child(3) {
text-align: right;
}
</style>
97 changes: 53 additions & 44 deletions src/Document.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,56 +9,65 @@ onMounted(() => {
</script>

<template>
<h3>Simple camera simulator</h3>
<div class="info">
<h3>Simple camera simulator</h3>

<dl>
<dt>Lensmaker's equation</dt>
<dd>
<p>
$$
\begin{eqnarray}
\frac{1}{f} = (n - 1)\left(\frac{1}{R_1} - \frac{1}{R_2}\right) + \frac{d(n-1)^2}{R_1 R_2}
\end{eqnarray}
$$
\(f\) : Focal length<br>
\(n\) : Refractive index<br>
\(R_1\) : Radius of curvature of the left side of surface (positive).<br>
\(R_2\) : Radius of curvature of the right side of surface (negative).<br>
\(d\) : Thickness (distance between left and right surface on the optical axis).<br>
</p>
<p>
In this application, we assume \(R = R_1 = -R_2 > 0\), and
\(d\) is replaced by \(d = 2(R - \sqrt{R^2 - r^2})\) where \(r\) is radius of the lens.
Then, the equation becomes
$$
\begin{eqnarray}
\frac{1}{f} = \frac{2(n-1)}{R} + \frac{2(R - \sqrt{R^2 - r^2})(n-1)^2}{R^2}.
\end{eqnarray}
$$
And, \(f\), \(n\) and \(r\) are our parameters. \(R\) is calculated by solving this equation for \(R\).
To solve this equation, numerical method (Newton's method) is performed because quartic equation is hard
to solve.
</p>
</dd>
<dl>
<dt>Lensmaker's equation</dt>
<dd>
<p>
$$
\begin{eqnarray}
\frac{1}{f} = (n - 1)\left(\frac{1}{R_1} - \frac{1}{R_2}\right) + \frac{d(n-1)^2}{R_1 R_2}
\end{eqnarray}
$$
\(f\) : Focal length<br>
\(n\) : Refractive index<br>
\(R_1\) : Radius of curvature of the left side of surface (positive).<br>
\(R_2\) : Radius of curvature of the right side of surface (negative).<br>
\(d\) : Thickness (distance between left and right surface on the optical axis).<br>
</p>
<p>
In this application, we assume \(R = R_1 = -R_2 > 0\), and
\(d\) is replaced by \(d = 2(R - \sqrt{R^2 - r^2})\) where \(r\) is radius of the lens.
Then, the equation becomes
$$
\begin{eqnarray}
\frac{1}{f} = \frac{2(n-1)}{R} + \frac{2(R - \sqrt{R^2 - r^2})(n-1)^2}{R^2}.
\end{eqnarray}
$$
And, \(f\), \(n\) and \(r\) are our parameters. \(R\) is calculated by solving this equation for
\(R\).
To solve this equation, numerical method (Newton's method) is performed because quartic equation is
hard
to solve.
</p>
</dd>

<!-- <dt><a href="https://en.wikipedia.org/wiki/Focal_length">Focal length</a></dt> -->
</dl>
<!-- <dt><a href="https://en.wikipedia.org/wiki/Focal_length">Focal length</a></dt> -->
</dl>

<h3>Notice</h3>
<ul>
<li>Theoretical correctness is not guaranteed.</li>
<li>Here, we assume that the camera lens is singe symmetric spherical convex lens. The real camera lens is
composed
from multiple types of lenses.</li>
<li>The rays inside the ideal lens are not visualized correctly. The rays are refracted at the center plane of
the
lens.</li>
<li>The visual may differ depending on the browser.</li>
<li>Enabling GPU acceleration is highly recommended. (e.g. Enable Vulcan for Chrome)</li>
</ul>
<h3>Notice</h3>
<ul>
<li>Theoretical correctness is not guaranteed.</li>
<li>Here, we assume that the camera lens is singe symmetric spherical convex lens. The real camera lens is
composed
from multiple types of lenses.</li>
<li>The rays inside the ideal lens are not visualized correctly. The rays are refracted at the center plane
of
the
lens.</li>
<li>The visual may differ depending on the browser.</li>
<li>Enabling GPU acceleration is highly recommended. (e.g. Enable Vulcan for Chrome)</li>
</ul>
</div>
</template>

<style scoped>
.info {
padding: 0.5em;
}
dt {
font-weight: bold;
}
Expand Down
Loading

0 comments on commit 050ca5b

Please sign in to comment.