Skip to content

Commit

Permalink
Merge pull request #248 from PRIME-TU-Delft/#57-solution-sets
Browse files Browse the repository at this point in the history
added applet solution sets
  • Loading branch information
yustarandomname authored Oct 4, 2024
2 parents 13ea004 + 3023da6 commit f686ff1
Show file tree
Hide file tree
Showing 7 changed files with 292 additions and 19 deletions.
55 changes: 55 additions & 0 deletions src/lib/threlte/InfiniteLine3D.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<script lang="ts">
import { PrimeColor } from '$lib/utils/PrimeColors';
import { T } from '@threlte/core';
import { MeshLineGeometry, MeshLineMaterial } from '@threlte/extras';
import { BufferGeometry, Line, Mesh, Vector3 } from 'three';
import Line3D from './Line3D.svelte';
type LineProps = {
origin?: Vector3;
direction: Vector3;
color?: string;
isDashed?: boolean;
radius?: number;
alwaysOnTop?: boolean;
};
let {
origin = new Vector3(0, 0, 0),
direction = new Vector3(1, 0, 0),
color = PrimeColor.getRandomColor(),
isDashed = false,
radius = 0,
alwaysOnTop = false
}: LineProps = $props();
</script>

<!--@component
@props
- origin: Vector3 = `new Vector3(0, 0, 0)` - The origin of the line
- endPoint: Vector3 = `new Vector3(0, 0, 0)` - The end point of the line
- color: string = `PrimeColor.getRandomColor()` - The color of the line
- isDashed: boolean = `false` - If the line is dashed
- radius: number = `0` - The radius of the line (0 means thin line, >0 means a tube)
- alwaysOnTop: boolean = `false` - If the line should always be on top
@example
<InfiniteLine3D direction={v} color={PrimeColor.blue} />
-->

<Line3D
{origin}
endPoint={origin.clone().add(direction.clone().normalize().multiplyScalar(30))}
{color}
{isDashed}
{radius}
{alwaysOnTop}
/>
<Line3D
{origin}
endPoint={origin.clone().add(direction.clone().normalize().multiplyScalar(-30))}
{color}
{isDashed}
{radius}
{alwaysOnTop}
/>
17 changes: 14 additions & 3 deletions src/lib/threlte/Latex3D.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,20 @@
hasBackground = false
}: Latex2DProps = $props();
const pos = $derived(
position.clone().add(offset).add(position.clone().normalize().multiplyScalar(extend))
);
const pos = $derived.by(() => {
const posOffset = position.clone().add(offset);
// If extend is 0, return the position with the offset
if (extend == 0) return posOffset;
// If position is the origin, return the offset with the extend vector
// This is to avoid the 0 vector
if (position.length() == 0) {
return posOffset.add(new Vector3(1, 1, 1).normalize().multiplyScalar(extend));
}
return posOffset.add(position.clone().normalize().multiplyScalar(extend));
});
const classes = $derived(
cn(
Expand Down
13 changes: 9 additions & 4 deletions src/lib/threlte/Vector3D.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { DoubleSide, Mesh, Quaternion, Vector3 } from 'three';
import Line3D from './Line3D.svelte';
import type { Snippet } from 'svelte';
import Point3D from './Point3D.svelte';
type Vector3DProps = {
color?: string;
Expand Down Expand Up @@ -83,10 +84,14 @@

<!-- Cone on top of line -->
{#if !hideHead}
<T.Mesh position={conePosition.toArray()} bind:ref={coneMesh}>
<T.MeshBasicMaterial {color} side={DoubleSide} />
<T.ConeGeometry args={[CONE_DIAMETER * radius, CONE_HEIGHT, RADIUS_SEGMENTS]} />
</T.Mesh>
{#if length == 0}
<Point3D position={origin} {color} />
{:else}
<T.Mesh position={conePosition.toArray()} bind:ref={coneMesh}>
<T.MeshBasicMaterial {color} side={DoubleSide} />
<T.ConeGeometry args={[CONE_DIAMETER * radius, CONE_HEIGHT, RADIUS_SEGMENTS]} />
</T.Mesh>
{/if}
{/if}

{#if children}
Expand Down
28 changes: 16 additions & 12 deletions src/lib/threlte/planes/PlaneFromPoints.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
type PlaneFromPointsProps = {
points: [Vector3, Vector3, Vector3];
origin?: Vector3;
color?: string;
size?: number;
opacity?: number;
Expand All @@ -16,6 +17,7 @@
let {
points = [new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1)],
origin = new Vector3(),
color = PrimeColor.getRandomColor(),
size = 10,
opacity = 0.8,
Expand All @@ -39,16 +41,18 @@
});
</script>

<T.Mesh material={materials} bind:ref={planeMesh}>
<T.PlaneGeometry
args={[size, size, planeSegment.segments, 1]}
oncreate={({ ref }: { ref: PlaneGeometry }) => {
for (let i = 0; i < planeSegment.segments; i++) {
if (i % planeSegment.interval == planeSegment.offset) {
// A rectangle consists of two triangles 6 vertices
ref.addGroup(i * 6, 6, 0);
<T.Group position.x={origin.x} position.y={origin.y} position.z={origin.z}>
<T.Mesh material={materials} bind:ref={planeMesh}>
<T.PlaneGeometry
args={[size, size, planeSegment.segments, 1]}
oncreate={({ ref }: { ref: PlaneGeometry }) => {
for (let i = 0; i < planeSegment.segments; i++) {
if (i % planeSegment.interval == planeSegment.offset) {
// A rectangle consists of two triangles 6 vertices
ref.addGroup(i * 6, 6, 0);
}
}
}
}}
/>
</T.Mesh>
}}
/>
</T.Mesh>
</T.Group>
4 changes: 4 additions & 0 deletions src/lib/utils/MathLib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export function round(x: number, precision = 2) {
return Math.round(x * factor) / factor;
}

export function roundString(x: number, precision = 2) {
return round(x, precision).toString();
}

/**
* The snapPointToLine function calculates the smallest distance from a point to a line.
* It then returns the closest point on that line if the actual distance is smaller than the required distance
Expand Down
98 changes: 98 additions & 0 deletions src/routes/applet/solution_sets/two_lines_in_r3/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<script>
import { Controls } from '$lib/controls/Controls';
import Axis3D from '$lib/threlte/Axis3D.svelte';
import Canvas3D from '$lib/threlte/Canvas3D.svelte';
import InfiniteLine3D from '$lib/threlte/InfiniteLine3D.svelte';
import Latex3D from '$lib/threlte/Latex3D.svelte';
import Vector3D from '$lib/threlte/Vector3D.svelte';
import { Formula } from '$lib/utils/Formulas';
import { round, roundString } from '$lib/utils/MathLib';
import { MathVector3 } from '$lib/utils/MathVector';
import { PrimeColor } from '$lib/utils/PrimeColors';
import { Vector3 } from 'three';
const controls = Controls.addSlider(4, -5, 6, 0.5, PrimeColor.raspberry, {
label: 'a',
valueFn: roundString
});
const v = new MathVector3(-4, 3, 1);
const v_offset = $derived(new MathVector3(-controls[0], controls[0], 0));
const formulas = $derived.by(() => {
const minusA = round(-controls[0]);
const f1 = new Formula(
`\\$1: \\Bigg\\lbrace
\\begin{bmatrix}\\$2 \\\\ \\$3 \\\\0 \\end{bmatrix} +
t \\space \\begin{bmatrix}-4 \\\\ 3 \\\\ 1 \\end{bmatrix} \\space | \\space
t \\in \\mathbb{R} \\Bigg\\rbrace`
)
.addAutoParam('\\mathcal{L_2}', PrimeColor.darkGreen)
.addAutoParam(minusA, PrimeColor.raspberry)
.addAutoParam(round(controls[0]), PrimeColor.raspberry);
return [f1];
});
</script>

<Canvas3D {controls} {formulas} cameraPosition={new Vector3(-6, 4.5, 15.5)} showFormulasDefault>
<!-- Default -->
<Vector3D direction={v} length={v.length()} color={PrimeColor.yellow} alwaysOnTop />
<Latex3D
latex={'\\mathbf{v}'}
position={v}
extend={0.5}
offset={new Vector3(0, 0, 0.5)}
color={PrimeColor.yellow}
/>

<InfiniteLine3D radius={0.5} direction={v} color={PrimeColor.blue} />

<Latex3D
latex={'\\mathcal{L_1}'}
position={v.clone().multiplyScalar(2)}
extend={0.5}
offset={new Vector3(0.1, 0, 0.75)}
color={PrimeColor.blue}
/>

<!-- Extended -->
<Vector3D
origin={v_offset}
direction={v}
length={v.length()}
color={PrimeColor.yellow}
alwaysOnTop
/>
<Latex3D
offset={v_offset.clone().add(new Vector3(0, 0, 0.5))}
latex={'\\mathbf{v}'}
position={v}
extend={0.5}
color={PrimeColor.yellow}
/>

<InfiniteLine3D radius={0.5} origin={v_offset} direction={v} color={PrimeColor.darkGreen} />

<Latex3D
latex={'\\mathcal{L_2}'}
position={v_offset.clone().add(v.clone().multiplyScalar(2))}
extend={0.5}
offset={new Vector3(0.1, 0, 0.75)}
color={PrimeColor.darkGreen}
/>

<!-- R0 -->
<Vector3D direction={v_offset} length={v_offset.length()} color={PrimeColor.raspberry} />
<Latex3D
latex={'\\mathbf{r_0}'}
position={v_offset}
extend={0.5}
offset={new Vector3(0, 0, 0.5)}
color={PrimeColor.raspberry}
/>

<Axis3D />
</Canvas3D>
96 changes: 96 additions & 0 deletions src/routes/applet/solution_sets/two_planes_in_r3/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<script>
import { Controls } from '$lib/controls/Controls';
import Axis3D from '$lib/threlte/Axis3D.svelte';
import Canvas3D from '$lib/threlte/Canvas3D.svelte';
import Latex3D from '$lib/threlte/Latex3D.svelte';
import PlaneFromPoints from '$lib/threlte/planes/PlaneFromPoints.svelte';
import Vector3D from '$lib/threlte/Vector3D.svelte';
import { Formula } from '$lib/utils/Formulas';
import { round, roundString } from '$lib/utils/MathLib';
import { MathVector3 } from '$lib/utils/MathVector';
import { PrimeColor } from '$lib/utils/PrimeColors';
import { Vector3 } from 'three';
const controls = Controls.addSlider(7, 1, 10, 0.5, PrimeColor.raspberry, {
label: 'a',
valueFn: roundString
});
const v1 = new MathVector3(-3, 1, 0);
const v2 = new MathVector3(1, 0, 1);
const v3 = $derived(new Vector3(0, 0, controls[0]));
const formulas = $derived.by(() => {
const f1 = new Formula(
`\\$1: \\Bigg\\lbrace
\\begin{bmatrix}\\$2 \\\\ 0 \\\\0 \\end{bmatrix} +
s \\space \\begin{bmatrix}-3 \\\\ 1 \\\\ 0 \\end{bmatrix} +
t \\space \\begin{bmatrix}1 \\\\ 0 \\\\ 1 \\end{bmatrix} \\space | \\space
s, t \\in \\mathbb{R} \\Bigg\\rbrace`
)
.addAutoParam('\\mathcal{P_2}', PrimeColor.darkGreen)
.addAutoParam(round(controls[0], 1), PrimeColor.raspberry);
return [f1];
});
</script>

<Canvas3D {controls} {formulas} cameraPosition={new Vector3(-8, 8, 12.5)} showFormulasDefault>
<!-- Default -->
<Vector3D direction={v1} length={v1.length()} color={PrimeColor.yellow} />
<Latex3D latex={'\\mathbf{v_1}'} position={v1} extend={0.5} color={PrimeColor.yellow} />

<Vector3D direction={v2} length={v2.length()} color={PrimeColor.orange} />
<Latex3D latex={'\\mathbf{v_2}'} position={v2} extend={0.5} color={PrimeColor.orange} />

<PlaneFromPoints points={[v1, v2, new Vector3()]} color={PrimeColor.blue} opacity={0.5} />

<Latex3D
latex={'\\mathcal{P_1}'}
position={new Vector3(0, 0, 0)}
extend={0.5}
offset={v2.clone().multiplyScalar(4.25)}
color={PrimeColor.blue}
/>

<!-- Extended -->
<Vector3D origin={v3} direction={v1} length={v1.length()} color={PrimeColor.yellow} />
<Latex3D
offset={v3}
latex={'\\mathbf{v_1}'}
position={v1}
extend={0.5}
color={PrimeColor.yellow}
/>

<Vector3D origin={v3} direction={v2} length={v2.length()} color={PrimeColor.orange} />
<Latex3D
offset={v3}
latex={'\\mathbf{v_2}'}
position={v2}
extend={0.5}
color={PrimeColor.orange}
/>

<PlaneFromPoints
origin={v3}
points={[v1, v2, new Vector3()]}
color={PrimeColor.darkGreen}
opacity={0.5}
/>

<Latex3D
latex={'\\mathcal{P_2}'}
position={v3}
extend={0.5}
offset={v2.clone().multiplyScalar(4.5)}
color={PrimeColor.darkGreen}
/>

<!-- R_0 -->
<Vector3D direction={v3} length={v3.length()} color={PrimeColor.raspberry} />
<Latex3D latex={'\\mathbf{r_0}'} position={v3} extend={0.5} color={PrimeColor.raspberry} />

<Axis3D />
</Canvas3D>

0 comments on commit f686ff1

Please sign in to comment.