Move files to public folder
This commit is contained in:
108
public/CTAccordion .js
Normal file
108
public/CTAccordion .js
Normal file
@@ -0,0 +1,108 @@
|
||||
export const steps = [
|
||||
{
|
||||
title: "1. Upload / Input Image",
|
||||
content: `You upload or use a default grayscale image. This is treated like a 2D slice of a physical object.
|
||||
|
||||
The input image is a 2D function:
|
||||
$ f(x, y) $
|
||||
This represents how much X-rays are absorbed at each point.`,
|
||||
},
|
||||
{
|
||||
title: "2. Radon Transform (Generating the Sinogram)",
|
||||
content: `We rotate a virtual X-ray beam around the image and compute line integrals at each angle — simulating how X-rays pass through.
|
||||
|
||||
\\[
|
||||
R(\\theta, s) = \\int_{-\\infty}^{\\infty} f(s \\cos\\theta - t \\sin\\theta,\\ s \\sin\\theta + t \\cos\\theta)\\ dt
|
||||
\\]
|
||||
|
||||
Where: <br>
|
||||
- $\\theta$ = projection angle <br>
|
||||
- $s$ = offset from center
|
||||
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: "3. Sinogram",
|
||||
content: `You now have a 2D image where:
|
||||
- X-axis = detector position
|
||||
- Y-axis = angle
|
||||
Each row is a projection.
|
||||
|
||||
Math:
|
||||
$\text{Sinogram} = \{ R(\theta_1, s), R(\theta_2, s), \dots, R(\theta_n, s) \}$
|
||||
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: "4. Optional: Apply Ramp Filter (FBP)",
|
||||
content: `If enabled, we sharpen each projection before back-projecting by amplifying high-frequency content.
|
||||
|
||||
Math:
|
||||
\\[
|
||||
P(\\omega) = \\mathcal{F}[R(\\theta, s)] \\\\
|
||||
P'(\\omega) = |\\omega| \\cdot P(\\omega) \\\\
|
||||
\\text{Filtered Projection} = \\mathcal{F}^{-1}[P'(\\omega)]
|
||||
\\]
|
||||
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: "5. Back Projection",
|
||||
content: `Each (filtered) projection is \"smeared\" back into the image space along its angle.
|
||||
|
||||
\\[
|
||||
f'(x, y) = \\int_0^{\\pi} R'(\\theta,\\ x \\cos\\theta + y \\sin\\theta)\\ d\\theta
|
||||
\\]`,
|
||||
},
|
||||
{
|
||||
title: "6. Final Reconstruction",
|
||||
content: `After all angles are added up, you get a reconstructed image resembling the original.
|
||||
|
||||
\[
|
||||
f'(x, y) \approx f(x, y)
|
||||
\]`,
|
||||
},
|
||||
];
|
||||
|
||||
export const StepAccordion = {
|
||||
view(vnode) {
|
||||
const index = vnode.attrs.index;
|
||||
const step = steps[index];
|
||||
const expanded = vnode.state.expanded ?? false;
|
||||
|
||||
return m("div", { class: "border-b border-gray-300 py-1 my-2" }, [
|
||||
m(
|
||||
"button",
|
||||
{
|
||||
class:
|
||||
"w-full text-left font-bold text-lg text-gray-800 focus:outline-none",
|
||||
onclick: () => {
|
||||
vnode.state.expanded = !vnode.state.expanded;
|
||||
},
|
||||
},
|
||||
step.title
|
||||
),
|
||||
vnode.state.expanded &&
|
||||
m(
|
||||
"div",
|
||||
{
|
||||
class: "mt-2 text-gray-700 whitespace-pre-wrap text-sm",
|
||||
onupdate: () => {
|
||||
if (window.MathJax) window.MathJax.typesetPromise();
|
||||
},
|
||||
},
|
||||
m.trust(markdownToHTML(step.content))
|
||||
),
|
||||
]);
|
||||
},
|
||||
};
|
||||
|
||||
// You must provide a markdownToHTML() function or use a library like marked.js
|
||||
function markdownToHTML(text) {
|
||||
return text
|
||||
.replace(/\n/g, "<br>")
|
||||
.replace(
|
||||
/!\[(.*?)\]\((.*?)\)/g,
|
||||
'<img alt="$1" src="$2" class="my-2 rounded shadow max-w-full">'
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user