Skip to content

Commit 71b29fb

Browse files
committed
Add Lagrange demo
1 parent aeb53db commit 71b29fb

File tree

7 files changed

+516
-176
lines changed

7 files changed

+516
-176
lines changed

media/src/Panel.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@
404404
{scene}
405405
render={requestFrameIfNotRequested}
406406
animate={animateIfNotAnimating}
407+
{selectedPoint}
407408
/>
408409
</TabPane>
409410
<TabPane

media/src/Story.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import SurfaceArea from './stories/SurfaceArea.svelte';
88
import FluxIntegral from './stories/FluxIntegral.svelte';
99
10-
let { scene, render, animate = () => {} } = $props();
10+
let { scene, render, animate = () => {}, selectedPoint } = $props();
1111
1212
/**
1313
* @type {typeof import('./stories/Blank.svelte').default}
@@ -32,7 +32,7 @@
3232
</div>
3333

3434
<div class="story-content-box">
35-
<CurrentStory {scene} {render} {animate} />
35+
<CurrentStory {scene} {render} {animate} {selectedPoint} />
3636
</div>
3737

3838
<style>

media/src/form-components/PlayButtons.svelte

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,17 @@
3434
<button class="btn rewbtn" onclick={rew} aria-label="rewind">
3535
<i class="fa fa-fast-backward"></i>
3636
</button>
37-
<button class="btn modebtn" onclick={clicker} aria-label="play mode">
38-
{#if playMode == 'loop'}
39-
<i class="fa fa-retweet"></i>
40-
{:else if playMode == 'once'}
41-
<i class="fa fa-arrow-right"></i>
42-
{:else}
43-
<i class="fa fa-arrows-alt-h"></i>
44-
{/if}
45-
</button>
37+
{#if ['loop', 'once', 'bounce'].indexOf(playMode) > -1}
38+
<button class="btn modebtn" onclick={clicker} aria-label="play mode">
39+
{#if playMode == 'loop'}
40+
<i class="fa fa-retweet"></i>
41+
{:else if playMode == 'once'}
42+
<i class="fa fa-arrow-right"></i>
43+
{:else}
44+
<i class="fa fa-arrows-alt-h"></i>
45+
{/if}
46+
</button>
47+
{/if}
4648
</div>
4749

4850
<style>

media/src/objects/Level.svelte

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
2121
import { marchingCubes, ArrowBufferGeometry, checksum } from '../utils.js';
2222
import { flashDance } from '../sceneUtils';
23+
import { mathToJSFunction } from './mathutils';
2324
2425
let {
2526
uuid,
@@ -121,12 +122,12 @@
121122
scene.add(mesh);
122123
123124
const updateLevel = function () {
124-
loading = true;
125-
const gc = math.parse(params.g).compile();
126-
updateParams(gc, params).then((data) => {
127-
levelWorkerSuccessHandler(data);
128-
onRenderObject(plusMesh, minusMesh);
129-
});
125+
// loading = true;
126+
// const gc = math.parse(params.g).compile();
127+
// Still blocks but will load scene/axes at load before minitask runs
128+
const data = updateParams(params.g, params);
129+
levelWorkerSuccessHandler(data);
130+
onRenderObject(plusMesh, minusMesh);
130131
};
131132
132133
/**
@@ -215,6 +216,7 @@
215216
}
216217
217218
point.position.set(0, 0, 0);
219+
frameVisible = false;
218220
219221
tangentVectors({ point });
220222
@@ -257,7 +259,7 @@
257259
let choosingPoint = $state(false);
258260
const pointMaterial = new THREE.MeshLambertMaterial({ color: 0xffff33 });
259261
const point = new THREE.Mesh(
260-
new THREE.SphereGeometry(0.2 / 8, 16, 16),
262+
new THREE.SphereGeometry(0.1 / 8, 16, 16),
261263
pointMaterial,
262264
);
263265
@@ -274,17 +276,29 @@
274276
new THREE.BufferGeometry(),
275277
shardMaterial,
276278
);
279+
280+
planeShard.visible = false;
281+
277282
tanFrame.add(planeShard);
278283
279284
let frameVisible = $state(false);
280285
$effect(() => {
281286
tanFrame.visible = frameVisible;
282287
});
288+
let planeVisible = $state(false);
289+
$effect(() => {
290+
planeShard.visible = planeVisible;
291+
});
292+
let normalVisible = $state(false);
293+
$effect(() => {
294+
arrows.n.visible = normalVisible;
295+
});
283296
284297
scene.add(tanFrame);
285298
286299
const nFrame = function ({
287-
f = (x, y, z) => math.evaluate(params.g, { x, y, z }),
300+
f = mathToJSFunction(params.g, ['x', 'y', 'z']),
301+
// math.evaluate(params.g, { x, y, z }),
288302
point = point,
289303
eps = 1e-4,
290304
} = {}) {
@@ -421,20 +435,20 @@
421435
render();
422436
break;
423437
case 'y':
424-
if (!planeShard.visible) {
438+
if (!planeVisible) {
425439
frameVisible = true;
426-
planeShard.visible = true;
440+
planeVisible = true;
427441
} else {
428-
planeShard.visible = false;
442+
planeVisible = false;
429443
}
430444
render();
431445
break;
432446
case 'n':
433-
if (!arrows.n.visible) {
447+
if (!normalVisible) {
434448
frameVisible = true;
435-
arrows.n.visible = true;
449+
normalVisible = true;
436450
} else {
437-
arrows.n.visible = false;
451+
normalVisible = false;
438452
}
439453
440454
render();
@@ -560,7 +574,7 @@
560574
/>
561575
</span>
562576
563-
<span class="box-1">Tangent plane </span>
577+
<span class="box-1">Point </span>
564578
<label class="switch box box-2">
565579
<input
566580
type="checkbox"
@@ -573,6 +587,28 @@
573587
<span class="slider round"></span>
574588
</label>
575589
{#if frameVisible}
590+
<span class="box-1">Tangent plane </span>
591+
<label class="switch box box-2">
592+
<input
593+
type="checkbox"
594+
name="tanPlaneVisible"
595+
id="tanPlaneVisible"
596+
bind:checked={planeVisible}
597+
onchange={render}
598+
/>
599+
<span class="slider round"></span>
600+
</label>
601+
<span class="box-1"> Normal </span>
602+
<label class="switch box box-2">
603+
<input
604+
type="checkbox"
605+
name="normalVisibla"
606+
id="normalVisibla"
607+
bind:checked={normalVisible}
608+
onchange={render}
609+
/>
610+
<span class="slider round"></span>
611+
</label>
576612
{#if choosingPoint}
577613
<button
578614
class="box box-2 btn btn-secondary"

media/src/objects/levelWorker.js

Lines changed: 24 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
import { create, all } from 'mathjs';
77

8+
import { mathToJSFunction } from "./mathutils";
9+
810
const config = {};
911
const math = create(all, config);
1012

@@ -16,58 +18,25 @@ const math = create(all, config);
1618
*/
1719
export function updateParams(gc, params) {
1820
const { a, b, c, d, e, f, k } = params;
19-
let paramErrors = {
20-
g: false,
21-
k: false
22-
};
23-
24-
return new Promise((resolve, reject) => {
25-
setTimeout(() => {
26-
const func = (x, y, z) => {
27-
try {
28-
return gc.evaluate({x, y, z});
29-
} catch (err) {
30-
paramErrors.g = true;
31-
return reject(paramErrors);
32-
}
33-
}
34-
35-
// Test compiled g eval with some basic xyz params, for
36-
// validation purposes.
37-
try {
38-
gc.evaluate({x: -2, y: -2, z: -2});
39-
} catch (err) {
40-
paramErrors.g = true;
41-
return reject(paramErrors);
42-
}
43-
44-
let kE = null;
45-
try {
46-
kE = math.evaluate(String(k));
47-
} catch (err) {
48-
paramErrors.k = true;
49-
return reject(paramErrors);
50-
}
5121

52-
const { normals, vertices, traceSegments } =
53-
marchingCubesWithTraces({
54-
f: func,
55-
level: kE,
56-
xMin: math.evaluate(String(a)),
57-
xMax: math.evaluate(String(b)),
58-
yMin: math.evaluate(String(c)),
59-
yMax: math.evaluate(String(d)),
60-
zMin: math.evaluate(String(e)),
61-
zMax: math.evaluate(String(f)),
62-
N: 30,
63-
});
64-
65-
resolve({
66-
normals, vertices, xpts: [], ypts: [], zpts: traceSegments
67-
});
68-
}, 0);
22+
const func = mathToJSFunction(gc, ['x', 'y', 'z']);
23+
24+
const { normals, vertices, traceSegments } = marchingCubesWithTraces({
25+
f: func,
26+
level: math.evaluate(String(k)),
27+
xMin: math.evaluate(String(a)),
28+
xMax: math.evaluate(String(b)),
29+
yMin: math.evaluate(String(c)),
30+
yMax: math.evaluate(String(d)),
31+
zMin: math.evaluate(String(e)),
32+
zMax: math.evaluate(String(f)),
33+
N: 60,
6934
});
70-
}
35+
return {
36+
normals, vertices, xpts: [], ypts: [], zpts: traceSegments
37+
};
38+
};
39+
7140

7241
const edgeTable = new Uint16Array([
7342
0x0, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905,
@@ -472,10 +441,10 @@ function marchingCubesWithTraces({
472441
zMax = 1,
473442
N = 30,
474443
xN = 10,
475-
/* eslint-disable */
444+
/* eslint-disable */
476445
yN = 10,
477446
zN = 10,
478-
/* eslint-enable */
447+
/* eslint-enable */
479448
} = {}) {
480449
// const geometry = new THREE.BufferGeometry();
481450

@@ -554,8 +523,8 @@ function marchingCubesWithTraces({
554523
const pt = pts[index];
555524

556525
const u = x + pt[0] * dx,
557-
v = y + pt[1] * dy,
558-
w = z + pt[2] * dz;
526+
v = y + pt[1] * dy,
527+
w = z + pt[2] * dz;
559528

560529
h = Math.max(u * eps, (2 * eps) ** 2);
561530
const fx = (f(u + h / 2, v, w) - f(u - h / 2, v, w)) / h;
@@ -564,7 +533,7 @@ function marchingCubesWithTraces({
564533
h = Math.max(w * eps, (2 * eps) ** 2);
565534
const fz = (f(u, v, w + h / 2) - f(u, v, w - h / 2)) / h;
566535
const inverseSquare =
567-
1 / math.sqrt(fx * fx + fy * fy + fz * fz);
536+
1 / math.sqrt(fx * fx + fy * fy + fz * fz);
568537

569538
vertices.push(u, v, w);
570539
normals.push(

0 commit comments

Comments
 (0)