personal_site/_posts/2100-12-30-template.md
2025-01-17 13:49:08 +00:00

373 lines
11 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title:
layout: post
excerpt: A one sentence summary.
draft: true
redirect_from: /template/
# Just a helper for the path if the page has lots of images.
images: /assets/images/2024
assets: # I often use this for model paths
# The thumbnail that goes on the blog or posts page. SVG if possible.
thumbnail: /assets/blog/template/thumbnail.svg
# The social media preview image, must be png or other raster.
social_image: /assets/blog/template/thumbnail.png
# The alt text for both images.
alt: An image of the text "{...}" to suggest the idea of a template.
image_class: invertable # For images that look good when inverted in dark modes by default they're dimmed
mathjax: true
head: |
<script async src="/node_modules/es-module-shims/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "/node_modules/three/build/three.module.min.js",
"three/addons/": "/node_modules/three/examples/jsm/",
"lil-gui": "/node_modules/lil-gui/dist/lil-gui.esm.min.js"
}
}
</script>
<script src="/assets/js/projects.js" type="module"></script>
---
This page acts as both a reminder of how I do various things on this blog and also serves as a canary to see if I've broken the layout inadvertently.
See [this kramdown cheatsheet](https://kramdown.gettalong.org/quickref.html)
## Subtitle
The first big project of the year was repainting this ladder up to our mezzanine bed. This ended up being so much more work than we expected, they say it's all in the surface prep and the surface prep here took ages with all the awkward corners.
There was one aspect that was fun with this which was that I made non-slip pads on the rungs by mixing the gloss paint with sand and painting over masked rectangle.
<figure>
<img src="{{page.images}}/train_view.jpeg">
<figcaption> A single large image. </figcaption>
</figure>
<figure class="two-wide">
<img src="{{page.images}}/ladder/late_into_the_night.jpeg">
<img src="{{page.images}}/ladder/finished.jpeg">
<figcaption> Two images side by side. </figcaption>
</figure>
<figure class="multiple">
<img src="{{page.images}}/chop_saw_dust_collector/print_preview.jpeg">
<img src="{{page.images}}/chop_saw_dust_collector/printing.jpeg">
<img src="{{page.images}}/chop_saw_dust_collector/installed.jpeg">
<figcaption> More than two images layed out nicely. </figcaption>
</figure>
Four images:
<figure class="multiple">
<img src="{{page.images}}/lasercutting/boxes.jpeg">
<img src="{{page.images}}/usbc_psu/case_proto_1.jpeg">
<img src="{{page.images}}/usbc_psu/case_proto_2.jpeg">
<img src="{{page.images}}/usbc_psu/case_proto_3.jpeg">
</figure>
A very long image:
<figure>
<img src="{{page.images}}/logos.jpeg">
<figcaption>Played around with some logo designs that I could stamp into ceramics.</figcaption>
</figure>
1. Item one
* sub item one
* sub item two
* sub item three
2. Item two
A table:
| Power | Voltage | Current |
|-------|---------|---------|
| 15W | 5 V | 3A |
| 27W | 9 V | 3A |
| 45W | 15 V | 3A |
| 60W | 20 V | 3A |
| 100W* | 20V | 5A |
## Line Element
So the setup is this: Imagine we draw a very short line vector $\vec{v}$ and let it flow along in a fluid with velocity field $u(\vec{x}, t)$.
<figure style="max-width: 250px;">
<img src="/assets/blog/astrophysical_fluids/line_element.svg" class="invertable">
<figcaption>A line element $\delta \vec{v}$ being dragged aloung in a fluid with velocity field $u(\vec{x}, t)$</figcaption>
</figure>
Three things will happen, the vector will be translated along, it will change length and it will change direction. If we ignore the translation, we can ask what the equation would be for the change in length and direction of $\vec{v}$. I'll drop the vector symbols on $v$, $u$ and $x$ from now on.
$$ D_t \; v = ? $$
If we assume $v$ is very small we can think about expanding $u$ to first order along $v$
$$ u(x + v, t) = u(x, t) + v \cdot \nabla u $$
where $v \cdot \nabla$ is the directional derivative $v_x \partial_x + v_y \partial_y + v_y \partial_y$ and when $v$ is infinitesimal it just directly tells us how $u$ will change if we move from point $x$ to point $x + v$.
So from this we can see that one end of our vector $v$ is moving along at $u(x, t)$ while the other end will move at $u(x, t) + v \cdot \nabla u$ hence:
$$ D_t \; v = v \cdot \nabla u $$
Below is a more “indexbyindex” look at how one carries out **Step 3** in detail. We start from
**math with color**:
$${\color{red} x} + {\color{blue} y}$$
$$
\frac{D}{Dt}\,\delta S_i
\;=\;
\varepsilon_{i j k}\,\bigl(\tfrac{D}{Dt}\delta x_j^{(1)}\bigr)\,\delta x_k^{(2)}
\;+\;
\varepsilon_{i j k}\,\delta x_j^{(1)}\,\bigl(\tfrac{D}{Dt}\delta x_k^{(2)}\bigr),
$$
and then substitute
$$
\frac{D}{Dt}\,\delta x_j^{(1)}
\;=\;
\delta x_\ell^{(1)}\,\frac{\partial u_j}{\partial x_\ell},
\quad
\frac{D}{Dt}\,\delta x_k^{(2)}
\;=\;
\delta x_\ell^{(2)}\,\frac{\partial u_k}{\partial x_\ell}.
$$
I like these underbraces:
$$
\frac{D}{Dt}\,\delta S_i
\;=\;
\underbrace{\varepsilon_{i j k}\,\delta x_\ell^{(1)}\,\frac{\partial u_j}{\partial x_\ell}\,\delta x_k^{(2)}}
_{T_{1}}
\;+\;
\underbrace{\varepsilon_{i j k}\,\delta x_j^{(1)}\,\delta x_\ell^{(2)}\,\frac{\partial u_k}{\partial x_\ell}}
_{T_{2}}.
$$
References:
[This is a link to the subtitle heading at the top of the page](#subtitle)
A [link][kramdown hp]
to the homepage.
[kramdown hp]: http://kramdown.gettalong.org "hp"
This is a text with a
footnote[^1].
[^1]: And here is the definition.
This is a text with a
footnote[^2].
[^2]:
And here is the definition.
> With a quote!
and some math
$$ x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} $$
* * *
<canvas style ="width: 100%;" id="myCanvas"></canvas>
<script type="module">
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { DragControls } from "three/addons/controls/DragControls.js";
let scene, camera, renderer;
let orbitControls, dragControls;
let sphereA, sphereB;
let arrowA, arrowB, arrowCross;
let objectsToDrag = [];
const d = 1;
init();
animate();
function init() {
const canvas = document.getElementById('myCanvas');
// --- Scene ---
scene = new THREE.Scene();
const aspect = canvas.clientWidth / canvas.clientHeight;
camera = new THREE.OrthographicCamera(
-d * aspect, // left
d * aspect, // right
d, // top
-d, // bottom
-100, // near
100 // far
);
camera.position.set(5, 5, 5);
camera.lookAt(0, 0, 0);
// --- Renderer (use the existing canvas) ---
renderer = new THREE.WebGLRenderer({ alpha: true, canvas: canvas, antialias: true });
renderer.setSize(canvas.clientWidth, canvas.clientHeight,);
// --- OrbitControls ---
orbitControls = new OrbitControls(camera, renderer.domElement);
// orbitControls.enableRotate = false; // Keep isometric
orbitControls.enablePan = false;
orbitControls.enableDamping = true;
orbitControls.dampingFactor = 0.05;
// const gridHelper = new THREE.GridHelper(5, 25, 0x444444, 0x888888);
// scene.add(gridHelper);
// --- Spheres for vector endpoints (draggable) ---
const sphereGeom = new THREE.SphereGeometry(0.08, 16, 16);
const sphereMat = new THREE.MeshStandardMaterial({ color: 0x000000 });
sphereA = new THREE.Mesh(sphereGeom, sphereMat);
sphereB = new THREE.Mesh(sphereGeom, sphereMat);
// Initial positions
sphereA.position.set(0, 0, 1);
sphereB.position.set(1, 0, 0);
scene.add(sphereA);
scene.add(sphereB);
objectsToDrag.push(sphereA, sphereB);
// --- Lights ---
const ambientLight = new THREE.AmbientLight(0xffffff, 0.7);
scene.add(ambientLight);
const dirLight = new THREE.DirectionalLight(0xffffff, 0.7);
dirLight.position.set(5, 5, 10);
scene.add(dirLight);
// --- Arrows for A, B, and A x B ---
const headLength = 0.1;
const headWidth = 0.1;
arrowA = new THREE.ArrowHelper(
new THREE.Vector3(1, 0, 0).normalize(),
new THREE.Vector3(0, 0, 0),
1,
0x000000, headLength, headWidth
);
arrowB = new THREE.ArrowHelper(
new THREE.Vector3(0, 1, 0).normalize(),
new THREE.Vector3(0, 0, 0),
1,
0x000000, headLength, headWidth
);
// Cross product arrow in red
arrowCross = new THREE.ArrowHelper(
new THREE.Vector3(0, 0, 1).normalize(),
new THREE.Vector3(0, 0, 0),
1,
0xff0000, headLength, headWidth
);
scene.add(arrowA);
scene.add(arrowB);
scene.add(arrowCross);
// --- DragControls ---
dragControls = new DragControls(objectsToDrag, camera, renderer.domElement);
// Disable orbiting during drag
dragControls.addEventListener('dragstart', function () {
orbitControls.enabled = false;
});
dragControls.addEventListener('dragend', function () {
orbitControls.enabled = true;
});
// Keep spheres in XZ plane, update arrows
dragControls.addEventListener('drag', (event) => {
event.object.position.y = 0;
updateArrows();
});
updateArrows();
window.addEventListener('resize', onWindowResize, false);
}
// Update arrow directions and lengths based on sphere positions
function updateArrows() {
const A = new THREE.Vector3().copy(sphereA.position);
const B = new THREE.Vector3().copy(sphereB.position);
// Update arrow A
const lengthA = A.length();
arrowA.setLength(lengthA, 0.2 * lengthA, 0.2 * lengthA);
arrowA.setDirection(A.clone().normalize());
arrowA.position.set(0, 0, 0);
// Update arrow B
const lengthB = B.length();
arrowB.setLength(lengthB, 0.2 * lengthB, 0.2 * lengthB);
arrowB.setDirection(B.clone().normalize());
arrowB.position.set(0, 0, 0);
// A x B
const cross = new THREE.Vector3().crossVectors(A, B);
const lengthCross = cross.length();
let directionCross = cross.clone().normalize();
// If cross is zero (or close to zero), set a default
if (isNaN(directionCross.x)) {
directionCross.set(0, 0, 1);
}
arrowCross.setDirection(directionCross);
arrowCross.setLength(lengthCross, 0.2 * lengthCross, 0.2 * lengthCross);
arrowCross.position.set(0, 0, 0);
}
function onWindowResize() {
const aspect = canvas.clientWidth / canvas.clientHeight;
camera.left = -d * aspect;
camera.right = d * aspect;
camera.top = d;
camera.bottom = -d;
camera.updateProjectionMatrix();
renderer.setSize(canvas.clientWidth, canvas.clientHeight);
}
function animate() {
requestAnimationFrame(animate);
orbitControls.update();
renderer.render(scene, camera);
}
</script>
<figure class="multiple">
<img src="/assets/images/alpha_test/original.jpg" class = "no-dim">
<img src="/assets/images/alpha_test/white_subtracted.png" class = "no-dim">
<img src="/assets/images/alpha_test/white_subtracted.png" class = "no-dim" style="filter: brightness(2);">
<img src="/assets/images/alpha_test/ai_subtracted.png">
<figcaption> Here are some images, (top left) original, (top right) white subtracted and replaced with alpha, (bottom left) same but brightened, (bottom right) ai background removal tool (loses shadow) </figcaption>
</figure>