jsxgraph-3d-workshop/challenges/sphere-contours.html

149 lines
4.9 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en">
<head>
<title>Sphere contour challenge</title>
<meta charset="UTF-8" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/jsxgraph/distrib/jsxgraph.css" />
<script type="text/javascript" charset="UTF-8" src="https://cdn.jsdelivr.net/npm/jsxgraph/distrib/jsxgraphcore.js"></script>
</head>
<body>
<h1>Sphere contour challenge</h1>
<p>Can you create something like this using <a href="https://jsxgraph.org/docs/symbols/Sphere3D.html#constructor"><code>Sphere3D</code></a>, <code>Plane3D</code>, and <a href="https://jsxgraph.org/docs/symbols/IntersectionCircle3D.html"><code>IntersectionCircle3D</code></a> elements? Dont worry about including the colors; theyre just to clarify what happens when you move the center of the sphere.</p>
<p>The <code>visible</code> attribute will come in handy.</p>
<p>Since the <code>create</code> call for <code>Plane3D</code> isnt documented, Ive included an <a href="#create-plane">example</a> below.</p>
<div id="sphere-contours" class="jxgbox" style="width:600px; height:600px"></div>
<h2 id="create-plane">How to create a 3D plane</h2>
<p>A <code>Plane3D</code> is created from a base point and two vectors. The base point can be given either in coordinates or as a <a href="https://jsxgraph.org/docs/symbols/Point3D.html#constructor"><code>Point3D</code></a>. The vectors are given in coordinates.</p>
<div id="plane-example" class="jxgbox" style="width:600px; height:600px"></div>
<!-- a solution to the sphere contour challenge -->
<script type="text/javascript">
// to prevent variable name conflicts, we define variables locally using `let`
// and put the code for each board in its own block
{
// create a JSXGraph board and draw a 3D view on it
let board = JXG.JSXGraph.initBoard(
'sphere-contours',
{
boundingbox: [-8, 8, 8,-8],
axis: false,
showCopyright: false,
showNavigation: false
}
);
let view = board.create(
'view3d',
[[-4.5, -4.5], [9, 9],
[[0, 3], [0, 3], [0, 3]]],
{
xPlaneRear: {fillOpacity: 0.2, gradient: null},
yPlaneRear: {fillOpacity: 0.2, gradient: null},
zPlaneRear: {fillOpacity: 0.2, gradient: null}
}
);
// create a base point
const nCuts = 3*4 + 1;
let cutPositions = Array.from({length: nCuts}, (_, k) => 0.25*k);
let cuttingPlanes = cutPositions.map(
x => view.create(
'plane3d',
[[x, 1.5, 1.5], [0, 1, 0], [0, 0, 1]],
{visible: false}
)
);
// create a center for a sphere
let center = view.create(
'point3d',
[1.5, 1.5, 1.5],
{
withLabel: false,
size: 5,
strokeWidth: 1,
strokeColor: '#300060',
fillColor: 'white',
gradientSecondColor: '#5000a0',
highlightStrokeColor: '#300060'
}
);
// create a sphere whose center is the point `center` and whose radius is 1
let sphere = view.create(
'sphere3d',
[center, 1],
{visible: false}
);
// intersect the sphere with each of the cutting planes
cuttingPlanes.forEach(
(plane, k) => view.create(
'intersectioncircle3d',
[plane, sphere],
{strokeColor: `rgb(${255*k/nCuts}, 0, 255)`}
)
);
}
</script>
<!-- how to create a 3D plane -->
<script type="text/javascript">
// to prevent variable name conflicts, we define variables locally using `let`
// and put the code for each board in its own block
{
// create a JSXGraph board and draw a 3D view on it
let board = JXG.JSXGraph.initBoard(
'plane-example',
{
boundingbox: [-8, 8, 8,-8],
axis: false,
showCopyright: false,
showNavigation: false
}
);
let view = board.create(
'view3d',
[[-4.5, -4.5], [9, 9],
[[0, 3], [0, 3], [0, 3]]],
{
xPlaneRear: {fillOpacity: 0.2, gradient: null},
yPlaneRear: {fillOpacity: 0.2, gradient: null},
zPlaneRear: {fillOpacity: 0.2, gradient: null}
}
);
// create a point
let basePoint = view.create(
'point3d',
[1, 1, 1],
{
withLabel: false,
size: 5,
strokeWidth: 1,
strokeColor: '#300060',
fillColor: 'white',
gradientSecondColor: '#5000a0',
highlightStrokeColor: '#300060'
}
);
// create a plane passing through the point
let plane = view.create(
'plane3d',
[basePoint, [-2, 1, 1], [1, -2, 1]],
{
strokeWidth: 1,
strokeColor: '#00ff80',
strokeOpacity: 0.5,
fillColor: '#00ff80',
fillOpacity: 0.1,
gradient: null
}
);
}
</script>
</body>
</html>