intersectionPlanePlane

15 views
Skip to first unread message

Holger Engels

unread,
Sep 7, 2022, 3:44:59 AM9/7/22
to JSXGraph
Hi,

I know, 3D is not officially supported yet, but I am already working with it .. I am trying to display the intersection line of two planes. I thought, I could achieve this with
the method intersectionPlanePlane of View3D like so:

---
<!doctype html>
<html lang="de">
<head>
<title>Ebene in Parameterform 3D</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />

<link rel='stylesheet' type='text/css' href='https://cdn.jsdelivr.net/npm/jsxgraph@latest/distrib/jsxgraph.css'/>
<script src='https://cdn.jsdelivr.net/npm/jsxgraph@latest/distrib/jsxgraphcore.js' type='text/javascript'></script>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@latest/dist/katex.min.css" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/katex@latest/dist/katex.min.js" crossorigin="anonymous"></script>

<style>
body {
margin: 0px;
padding: 0px;
overflow: hidden;
}
.container {
display: grid;
grid-template-columns: 1fr;
}
.jxgbox { border-radius: 0px; border: none}
.term { background-color: white }
</style>
</head>
<body>

<div class="container">
<div id='board' class='jxgbox' style='width: 100%; aspect-ratio: 1'></div>
</div>

<script type='text/javascript'>
var animating = undefined;
let r = {};
r._value = 0; r.Value = () => r._value;
let s = {};
s._value = 0; s.Value = () => s._value;

var board = JXG.JSXGraph.initBoard('board', { boundingbox: [-8, 8, 8, -8], keepaspectratio: false, axis: false, showNavigation: false, showZoom: false, showCopyright: false, pan: { enabled: false} });
var rs = board.create('slider', [[-3, -6.5], [5, -6.5], [-2, 0, 2]], { visible: () => !animating, snapWidth: .1, ticks: { drawLabels: true, label: {fontSize: 16, offset: [-4, -16]} }, name: 'r', digits: 1, label: { fontSize: 16, cssClass: 'term' }});
var ss = board.create('slider', [[-3, -7.5], [5, -7.5], [-2, 0, 2]], { visible: () => !animating, snapWidth: .1, ticks: { drawLabels: true, label: {fontSize: 16, offset: [-4, -16]} }, name: 's', digits: 1, label: { fontSize: 16, cssClass: 'term' }});

rs.on('drag', () => { r._value = rs.Value() });
ss.on('drag', () => { s._value = ss.Value() });

var toggle = board.create('button', [-7.5, -7, 'start/stop', function() {
if (!animating) {
animating = setInterval(() => {
var millis = +new Date();
millis = millis % 10000;
r._value = (2 * Math.sin(2 * Math.PI * millis / 10000));
s._value = (2 * Math.sin(8 * Math.PI * millis / 10000));
board.update();
}, 50);
}
else {
clearInterval(animating);
animating = undefined;
rs.setValue(r._value);
ss.setValue(s._value);
}
}]);

let box = [-6, 6];
var view = board.create('view3d',
[
[-6, -3], [8, 8], // 2D box of view
[box, box, box] // 3D bounding cube
],
{ xAxis: { visible: true }, yAxis: { visible: true }, zAxis: { visible: true },
xPlaneRear: {visible: false}, yPlaneRear: {visible: false}, zPlaneRear: {visible: false} });

let a = [3, -1, 2];
let b = [1.5, -3, -1.5];
let c = [3, 2, -1.5];
var p0 = view.create('point3d', [0, 0, 0], { visible: false });
var pa = view.create('point3d', a, { size: 3, name: '', visible: false });
var va = view.create('line3d', [p0, pa], { fixed: true, strokeColor: '#D55E00', strokeWidth: 3, lastArrow: { type: 2, size: 4 } });
var ta = view.create('point3d', [() => pa.D3.X() / 2, () => pa.D3.Y() / 2, () => pa.D3.Z() / 2 ], { visible: true, size: 0, label: { color: '#D55E00', useKatex: true, autoPosition: false }, name: '\\vec a' });
var pb = view.create('point3d', [() => pa.D3.X() + b[0], () => pa.D3.Y() + b[1], () => pa.D3.Z() + b[2]], { size: 3, name: '', visible: false });
var vb = view.create('line3d', [pa, pb], { fixed: true, strokeColor: 'blue', strokeWidth: 3, lastArrow: { type: 2, size: 4 } });
var tb = view.create('point3d', [() => pa.D3.X() + (pb.D3.X() - pa.D3.X()) / 2, () => pa.D3.Y() + (pb.D3.Y() - pa.D3.Y()) / 2, () => pa.D3.Z() + (pb.D3.Z() - pa.D3.Z()) / 2 ], { visible: true, size: 0, label: { color: 'blue', useKatex: true, autoPosition: false }, name: '\\vec b' });
var pc = view.create('point3d', [() => pa.D3.X() + c[0], () => pa.D3.Y() + c[1], () => pa.D3.Z() + c[2]], { size: 3, name: '', visible: false });
var vc = view.create('line3d', [pa, pc], { fixed: true, strokeColor: 'blue', strokeWidth: 3, lastArrow: { type: 2, size: 4 } });
var tc = view.create('point3d', [() => pa.D3.X() + (pc.D3.X() - pa.D3.X()) / 2, () => pa.D3.Y() + (pc.D3.Y() - pa.D3.Y()) / 2, () => pa.D3.Z() + (pc.D3.Z() - pa.D3.Z()) / 2 ], { visible: true, size: 0, label: { color: 'blue', useKatex: true, autoPosition: false }, name: '\\vec c' });
var px = view.create('point3d', [() => pa.D3.X() + r.Value() * (pb.D3.X() - pa.D3.X()) + s.Value() * (pc.D3.X() - pa.D3.X()), () => pa.D3.Y() + r.Value() * (pb.D3.Y() - pa.D3.Y()) + s.Value() * (pc.D3.Y() - pa.D3.Y()), () => pa.D3.Z() + r.Value() * (pb.D3.Z() - pa.D3.Z()) + s.Value() * (pc.D3.Z() - pa.D3.Z())], { size: 4, name: '', visible: true });
var vax = view.create('line3d', [pa, px], { fixed: true, strokeColor: 'black', strokeWidth: 3, lastArrow: { type: 2, size: 4 } });
var vx = view.create('line3d', [p0, px], { fixed: true, strokeColor: 'darkgray', strokeWidth: 3, dash: 2, lastArrow: { type: 2, size: 4 } });
var tx = view.create('point3d', [() => px.D3.X() / 2, () => px.D3.Y() / 2, () => px.D3.Z() / 2 ], { visible: true, size: 0, label: { color: 'black', useKatex: true }, name: '\\vec x' });

var p1 = view.create('point3d', [() => pa.D3.X() + 10 * (pb.D3.X() - pa.D3.X()), () => pa.D3.Y() + 10 * (pb.D3.Y() - pa.D3.Y()), () => pa.D3.Z() + 10 * (pb.D3.Z() - pa.D3.Z())], { size: 3, name: '', visible: true });
var p2 = view.create('point3d', [() => pa.D3.X() - 10 * (pb.D3.X() - pa.D3.X()), () => pa.D3.Y() - 10 * (pb.D3.Y() - pa.D3.Y()), () => pa.D3.Z() - 10 * (pb.D3.Z() - pa.D3.Z())], { size: 3, name: '', visible: true });

var plane = view.create('plane3d', [[() => pa.D3.X(), () => pa.D3.Y(), () => pa.D3.Z()], [() => pb.D3.X() - pa.D3.X(), () => pb.D3.Y() - pa.D3.Y(), () => pb.D3.Z() - pa.D3.Z()], [() => pc.D3.X() - pa.D3.X(), () => pc.D3.Y() - pa.D3.Y(), () => pc.D3.Z() - pa.D3.Z()], [-10, 10], [-10, 10]], {
fillColor: JXG.palette.blue, strokeWidth: 1, strokeColor: '#888888', strokeOpacity: 0.6, mesh3d: { visible: false }
});

let bn = JXG.Math.norm(b);
let cn = JXG.Math.norm(c);
var cx = view.create('curve3d', [
(t) => px.D3.X() + .7 * Math.cos(t) * b[0]/bn + .7 * Math.sin(t) * c[0]/cn,
(t) => px.D3.Y() + .7 * Math.cos(t) * b[1]/bn + .7 * Math.sin(t) * c[1]/cn,
(t) => px.D3.Z() + .7 * Math.cos(t) * b[2]/bn + .7 * Math.sin(t) * c[2]/cn,
[0, 2* Math.PI]], { strokeWidth: 3, visible: true, strokeColor: JXG.palette.blue });

var x1 = view.create('point3d', [20, 0, 0], { size: 3, name: '', visible: false });
var x2 = view.create('point3d', [-20, 0, 0], { size: 3, name: '', visible: false });
var gx = view.create('line3d', [x1, x2], { fixed: true, strokeColor: 'lightgray' });
var y1 = view.create('point3d', [0, 20, 0], { size: 3, name: '', visible: false });
var y2 = view.create('point3d', [0, -20, 0], { size: 3, name: '', visible: false });
var gy = view.create('line3d', [y1, y2], { fiyed: true, strokeColor: 'lightgray' });
var z1 = view.create('point3d', [0, 0, 20], { size: 3, name: '', visible: false });
var z2 = view.create('point3d', [0, 0, -20], { size: 3, name: '', visible: false });
var gz = view.create('line3d', [z1, z2], { fized: true, strokeColor: 'lightgray' });

var planex = view.create('plane3d', [[0, 0, 0], [0, 1, 0], [0, 0, 1]], { fillColor: JXG.palette.red, strokeColor: '#888888', strokeOpacity: 0.6, mesh3d: { visible: false } });
var planey = view.create('plane3d', [[0, 0, 0], [1, 0, 0], [0, 0, 1]], { fillColor: JXG.palette.green, strokeColor: '#888888', strokeOpacity: 0.6, mesh3d: { visible: false } });
var planez = view.create('plane3d', [[0, 0, 0], [0, 1, 0], [1, 0, 0]], { fillColor: JXG.palette.blue, strokeColor: '#888888', strokeOpacity: 0.6, mesh3d: { visible: false } });

var linex = view.create('line3d', view.intersectionPlanePlane(plane, planex, 0), { strokeColor: JXG.palette.red, strokeWidth: 2, strokeOpacity: 0.8 });
var liney = view.create('line3d', view.intersectionPlanePlane(plane, planey, 0), { strokeColor: JXG.palette.green, strokeWidth: 2, strokeOpacity: 0.8 });
var linez = view.create('line3d', view.intersectionPlanePlane(plane, planez, 0), { strokeColor: JXG.palette.blue, strokeWidth: 2, strokeOpacity: 0.8 });

var text = board.create('text', [7.5, 7.5, () => `g: \\vec x = \\textcolor{#D55E00}{\\begin{pmatrix} ${a[0]} \\\\ ${a[1]} \\\\ ${a[2]} \\end{pmatrix}} + r \\cdot \\textcolor{#0072B2}{\\begin{pmatrix} ${b[0]} \\\\ ${b[1]} \\\\ ${b[2]} \\end{pmatrix}} + s \\cdot \\textcolor{#0072B2}{\\begin{pmatrix} ${c[0]} \\\\ ${c[1]} \\\\ ${c[2]} \\end{pmatrix}}`], { visible: true, size: 0, useKatex: true, cssClass: 'term', anchorX: 'right', anchorY: 'top' });
</script>

</body>
</html>

---

Actually this creates some lines, but they are not the intersections of the planes, though they have at least one point in common with the intersecting planes :-/

Maybe anyone can shed some light on this?

Thanks and regards,

Holger

Holger Engels

unread,
Sep 7, 2022, 8:04:23 AM9/7/22
to JSXGraph
ah .. I found a solution ..
---
var linex = view.create('line3d', [
() => JXG.Math.Geometry.meet3Planes(plane.D3.normal, plane.D3.d, planex.D3.normal, planex.D3.d, JXG.Math.crossProduct(plane.D3.normal, planex.D3.normal), 0),
() => JXG.Math.Geometry.meetPlanePlane(plane.D3.dir1, plane.D3.dir2, planex.D3.dir1, planex.D3.dir2)],

{ strokeColor: JXG.palette.red, strokeWidth: 2, strokeOpacity: 0.8 });
var liney = view.create('line3d', [
() => JXG.Math.Geometry.meet3Planes(plane.D3.normal, plane.D3.d, planey.D3.normal, planey.D3.d, JXG.Math.crossProduct(plane.D3.normal, planey.D3.normal), 0),
() => JXG.Math.Geometry.meetPlanePlane(plane.D3.dir1, plane.D3.dir2, planey.D3.dir1, planey.D3.dir2)],

{ strokeColor: JXG.palette.green, strokeWidth: 2, strokeOpacity: 0.8 });
var linez = view.create('line3d', [
() => JXG.Math.Geometry.meet3Planes(plane.D3.normal, plane.D3.d, planez.D3.normal, planez.D3.d, JXG.Math.crossProduct(plane.D3.normal, planez.D3.normal), 0),
() => JXG.Math.Geometry.meetPlanePlane(plane.D3.dir1, plane.D3.dir2, planez.D3.dir1, planez.D3.dir2)],

{ strokeColor: JXG.palette.blue, strokeWidth: 2, strokeOpacity: 0.8 });

---
Reply all
Reply to author
Forward
0 new messages