Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matrices 3D Playground #238

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions content/matrices/content.md
Original file line number Diff line number Diff line change
Expand Up @@ -1211,3 +1211,146 @@ Let's see why this is true geometrically.
> sectionStatus: dev

{.todo} COMING SOON


----------------------------------------------------------------------------------------------------


## 3D playground

> id: three-dimensions

#### Watch what we can do with a 3d matrix
Watch what we can do with a 3d matrix.

::: column(width=280)

x-solid(size=280)

:::

Try adjusting the vector.
<table class="vector">
<tr>x = ${x}{x|-2|-2,2,0.1}</tr>
<tr>y = ${y}{y|-2|-2,2,0.1}</tr>
<tr>z = ${z}{z|-2|-2,2,0.1}</tr>
</table>

Neat, huh?

### Systems of Equations
A linear equation can be represented as a geometrical object, depending on how many variables it has. A linear equation with two variables can be represented as a [[line|plane|hypercube]]. A linear equation with three variables can be represented as a [[plane|line|point]].


x-solid(size=300)


Try adjusting the vector (only Z does anything).
<table class="vector">
<tr>x = ${xi}{xi|1|-2,2,0.1}</tr>
<tr>y = ${yi}{yi|1|-2,2,0.1}</tr>
<tr>z = ${zi}{zi|1|-2,2,0.1}</tr>
</table>

Above us is a system of three equations, each with three variables. The intersection of two of these planes gives us a [[line|plane|point]]. The intersection of all three of these planes gives us a [[point|line|plane]].


---

## Scroller playground
> id: scroller

Let's put a matrix on the right, and text on the left.

::: column(width=300)

// figure: img(src="images/proto-2/matrix-1-frn-fea.png")
table
tr
td
td(target="feature pref-A-1"): b {.m-red}Outdoors
td(target="feature pref-A-2"): b {.m-red}Veggie
tr
td.name(target="pref-A-1 pref-A-2"): b {.m-green}Alice
td.cell(target="pref-A-1") 1
td.cell(target="pref-A-2") 4
tr
td.name: b {.m-green}Bob
td.cell 3
td.cell 0
tr
td.name: b {.m-green}Charlie
td.cell 0
td.cell 4
tr
td.name: b {.m-green}Dave
td.cell 3
td.cell 0

div x

// figure: img(src="images/proto-2/matrix-1-fea-res.png")
table
tr
td
td(target="feat-A-1 feat-A-2"): b {.m-blue}Gauss
td: b {.m-blue}Laplace
td: b {.m-blue}Pizza
tr
td(target="feature feat-A-1"): b {.m-red}Outdoor
td.cell(target="feat-A-1") 3
td.cell 1
td.cell 3
tr
td(target="feature feat-A-2"): b {.m-red}Veggie
td.cell(target="feat-A-2") 1
td.cell 4
td.cell 3

// figure: img(src="images/proto-2/matrix-1-frn-res-empty.png")
// figure: img(src="images/proto-2/mult-alice-gauss.png") (and above)
// figure: img(src="images/proto-2/mult-bob-laplace.png") (and above)
// figure: img(src="images/proto-2/matrix-1-frn-res-full.png") (change into)
table
tr
td
td(target="rest cell-A"): b {.m-blue}Gauss
td(target="rest cell-C"): b {.m-blue}Laplace
td(target="rest"): b {.m-blue}Pizza
tr
td.name(target="friend cell-A"): b {.m-green}Alice
td.cell(target="cell-A"): b {.reveal(when="blank-5")} 7
td.cell
td.cell
tr
td.name(target="friend"): b {.m-green}Bob
td.cell
td.cell
td.cell
tr
td.name(target="friend cell-C"): b {.m-green}Charlie
td.cell
td.cell(target="cell-C"): b {.reveal(when="blank-7")} 16
td.cell
tr
td.name(target="friend"): b {.m-green}Dave
td.cell
td.cell
td.cell

::: column.grow(parent="right")

The result will be a new table with the [{.green} friends](target:friend) as [[rows|columns]] and the [{.blue} restaurants](target:rest) as [[columns|rows]].

{.reveal(when="blank-0 blank-1")} How should we fill out this table? The value of each cell should represent how much each person might like each restaurant. For example, the [{.orange} first cell](target:cell-A) will represent how much Alice might like [[Gauss Grill|Laplace Lounge]].

{.reveal(when="blank-2")} Alice has a [{.orange} preference of 1](target:pref-A-1) for Outdoor Seating, and Gauss Grill has a [{.orange} value of 3](target:feat-A-1) for Outdoor Seating, so we multiply these to get [[3]].

{.reveal(when="blank-3")} Alice has a [{.orange} preference of 4](target:pref-A-2) for Vegetarian Food, and Gauss Grill has a [{.orange}value of 1](target:feat-A-2) for Vegetarian Food, so we multiply these to get [[4]].

{.reveal(when="blank-4")} We sum together all the products to get [[7]], which we can write in the [{.orange} first cell](target:cell-A).

{.reveal(when="blank-5")}[Continue](btn:next)

{.reveal(when="next-0")} [{.teal} This cell](target:cell-C) will represent how much [[Charlie|Bob]] might like [[Laplace Lounge|Pizzathagoras]].
:::
127 changes: 127 additions & 0 deletions content/matrices/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {Matrix} from '@mathigon/fermat';
import {Angle, Point} from '@mathigon/euclid';
import {ElementView, ScreenEvent} from '@mathigon/boost';
import {Geopad, Step} from '../shared/types';
import {Solid} from '../shared/components/solid';
import * as u from './utils3d';


/**
Expand Down Expand Up @@ -341,3 +343,128 @@ export function determinants($step:Step) {
animateTransformationOnGeo($geopad, 'ipoint', 'jpoint', [[1, 1], [-1, -1]], ANIMATE);
});
}

export function threeDimensions($step: Step) {
const $solids = $step.$$('x-solid') as Solid[];

const basic3d = $solids[0];
basic3d.addMesh((scene) => {
// $solids[1].addWireframe(new THREE.Line)

// DRAW PLANES
const PLANE_SIZE = 4;
const zPlaneMaterial = Solid.translucentMaterial(0xcd0e66, 0.3);
const zPlane = new THREE.Mesh(new THREE.PlaneGeometry(PLANE_SIZE, PLANE_SIZE, 10, 10), zPlaneMaterial);
zPlane.rotateX(Math.PI / 2);
basic3d.addArrow([0, 0, 0], [0, 0, 1], 0xcd0e66);

const yPlaneMaterial = Solid.translucentMaterial(0x0f82f2, 0.3);
const yPlane = new THREE.Mesh(new THREE.PlaneGeometry(PLANE_SIZE, PLANE_SIZE, 10, 10), yPlaneMaterial);
yPlane.rotateY(Math.PI / 2);
basic3d.addArrow([0, 0, 0], [0, 1, 0], 0x0f82f2);

const xPlaneMaterial = Solid.translucentMaterial(0x22ab24, 0.3);
const xPlane = new THREE.Mesh(new THREE.PlaneGeometry(PLANE_SIZE, PLANE_SIZE, 10, 10), xPlaneMaterial);
xPlane.rotateZ(Math.PI / 2);
basic3d.addArrow([0, 0, 0], [1, 0, 0], 0x22ab24);

const vectorArrow = basic3d.addArrow([0, 0, 0], [$step.model.x, $step.model.y, $step.model.z], 0x000000);

$step.model.watch((state: any) => {
// A-HA! This doesn't work, and there's even a TODO to go with it
// "TODO Support changing the height of the arrow."
vectorArrow.updateEnds!([0, 0, 0], [state.x, state.y, state.z]);
scene.draw();
});

return [xPlane, yPlane, zPlane];
});

/**
* Add intersection lines to a solid.
* TODO: should use a new function in Fermat.js to calculate intersection lines.
*
* @param solid
*/
function addIntersectionLinesToSolid(solid: Solid) {

// intersection b/t Yellow and Cyan planes
// x + y + z = 1
// y = 1
solid.addLine([0, 1, 0], [-1, 1, 1], 0x00ff00);

// intersection b/t Magenta and Cyan planes
// z = 1, y = 1
solid.addLine([2, 1, 1], [-1, 1, 1], 0x0000ff);

// intersection b/t magenta and yellow planes
// x + y + z = 1
// z = 1
solid.addLine([0, 0, 1], [-1, 1, 1], 0xff0000);
}

const soq = $solids[1];
soq.addMesh((scene) => {

u.addUnitVectorsToSolid(soq);

// Plane for 1*x + 1*y + 1*z = 1
const planeYellow = u.planeFromNormal(
new THREE.Vector3(1, 1, 1),
new THREE.Vector3(1, 0, 0),
0xffff00
);
soq.object.add(planeYellow);

// Plane for 0*x + 1*y + 0*z = 1
// a.k.a. y=1
const planeCyan = u.planeFromNormal(
new THREE.Vector3(0, 1, 0),
new THREE.Vector3(0, 1, 0),
0x00ffff
);
soq.object.add(planeCyan);

// Plane for 0*x + 0*y + 1*z = 1
// a.k.a. z=1
const planeMagenta: THREE.Mesh = u.planeFromNormal(
new THREE.Vector3(0, 0, 1),
new THREE.Vector3(0, 0, 1),
0xff00ff
);
soq.object.add(planeMagenta);

addIntersectionLinesToSolid(soq);

// TODO: try this method
/* const px: THREE.Mesh = u.planeFromCoplanarPoints(
new Vector3(1, 0, 0),
new Vector3(0, 1, 0),
new Vector3(0, 0, 1),
0xff00ff
);
soq.object.add(px); */

$step.model.watch((state: any) => {

// this moves the plane at z=1 to z=zi
const newPlane = u.planeFromNormal(
new THREE.Vector3(0, 0, state.zi),
new THREE.Vector3(0, 0, state.zi),
0xff0ff
);
planeMagenta.geometry.dispose();
planeMagenta.geometry = newPlane.geometry;
scene.draw();

// not quite right...
/* const plane2 = u.planeFromNormal(
new THREE.Vector3(state.xi, state.yi, state.zi),
new THREE.Vector3(state.xi, state.yi, state.zi),
0xffff00
);
planeCyan.geometry.dispose();
planeCyan.geometry = plane2.geometry; */
});
});
}
Loading