405 lines
12 KiB
HTML
405 lines
12 KiB
HTML
|
<!DOCTYPE html>
|
|||
|
<html>
|
|||
|
<head>
|
|||
|
<title>3D polygon sampler</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>3D polygon sampler</h1>
|
|||
|
|
|||
|
<h2>Creating a polygon</h2>
|
|||
|
<p>A polygon is created from a list of vertices. Each vertex is given either in coordinates or as a <a href="https://jsxgraph.org/docs/symbols/Point3D.html#constructor"><code>Point3D</code></a> element. The vertices that are created from coordinates are styled according to the <code>vertices</code> attribute. The edges of the polygon are styled according to the <code>borders</code> attribute.</p>
|
|||
|
<p>To make the layout of the vertices easier to see, I’ve set the view’s <code>depthOrderPoints</code> attribute to <code>true</code>.
|
|||
|
<div id="polygon-homog-board" class="jxgbox" style="width:600px; height:600px"></div>
|
|||
|
|
|||
|
<h2>Mixing coordinates and <code>Point3D</code> elements</h2>
|
|||
|
<p>This example shows how you can mix coordinates and <a href="https://jsxgraph.org/docs/symbols/Point3D.html#constructor"><code>Point3D</code></a> elements in a polygon’s vertex list.</p>
|
|||
|
<div id="polygon-mixed-board" class="jxgbox" style="width:600px; height:600px"></div>
|
|||
|
|
|||
|
<h2>Filling a polygon</h2>
|
|||
|
<p>You can set the fill and opacity of a 3D polygon just like you would with a 2D polygon. I recommend only filling polygons that are guaranteed to stay planar. In this example, the polygons are always planar because they’re triangles.</p>
|
|||
|
<div id="planar-fill-board" class="jxgbox" style="width:600px; height:600px"></div>
|
|||
|
|
|||
|
<h2>The pitalls of filling a non-planar polygon</h2>
|
|||
|
<p>Make the polygon below non-planar by dragging its vertices. This will probably make the fill look really weird from certain angles.</p>
|
|||
|
<div id="non-planar-fill-board" class="jxgbox" style="width:600px; height:600px"></div>
|
|||
|
|
|||
|
<!-- creating a polygon -->
|
|||
|
<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(
|
|||
|
'polygon-homog-board',
|
|||
|
{
|
|||
|
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},
|
|||
|
depthOrderPoints: true
|
|||
|
}
|
|||
|
);
|
|||
|
|
|||
|
// create a list of individually styled Point3D elements to use as the
|
|||
|
// vertices of a polygon
|
|||
|
let vertices1 = [];
|
|||
|
coords1 = [
|
|||
|
[2, 1, 1],
|
|||
|
[2, 2, 1],
|
|||
|
[1, 2, 1],
|
|||
|
[1, 2, 2],
|
|||
|
[1, 1, 2],
|
|||
|
[1, 1, 1]
|
|||
|
];
|
|||
|
colors1 = [
|
|||
|
'orangered',
|
|||
|
'gold',
|
|||
|
'mediumseagreen',
|
|||
|
'darkturquoise',
|
|||
|
'purple',
|
|||
|
'deeppink'
|
|||
|
];
|
|||
|
for (i in coords1) {
|
|||
|
vertices1.push(view.create(
|
|||
|
'point3d',
|
|||
|
coords1[i],
|
|||
|
{
|
|||
|
withLabel: false,
|
|||
|
size: 5,
|
|||
|
strokeColor: 'none',
|
|||
|
fillColor: 'white',
|
|||
|
gradientSecondColor: colors1[i],
|
|||
|
highlightStrokeWidth: 1,
|
|||
|
highlightStrokeColor: '#777'
|
|||
|
}
|
|||
|
));
|
|||
|
}
|
|||
|
|
|||
|
// create a polygon from a list of vertices (given as Point3D elements)
|
|||
|
let polygon1 = view.create(
|
|||
|
'polygon3d',
|
|||
|
vertices1,
|
|||
|
{
|
|||
|
borders: {
|
|||
|
strokeColor: '#777',
|
|||
|
highlightStrokeColor: '#999'
|
|||
|
}
|
|||
|
}
|
|||
|
);
|
|||
|
|
|||
|
// create a polygon from a list of vertices (given in coordinates)
|
|||
|
let coords2 = [
|
|||
|
[0.5, 1.5, 1.5],
|
|||
|
[1.5, 1.5, 1.5],
|
|||
|
[1.5, 2.5, 1.5],
|
|||
|
[0.5, 2.5, 1.5]
|
|||
|
];
|
|||
|
let polygon2 = view.create(
|
|||
|
'polygon3d',
|
|||
|
coords2,
|
|||
|
{
|
|||
|
vertices: {
|
|||
|
withLabel: false,
|
|||
|
strokeColor: 'none',
|
|||
|
fillColor: 'white',
|
|||
|
gradientSecondColor: '#444',
|
|||
|
highlightStrokeWidth: 1,
|
|||
|
highlightStrokeColor: 'black'
|
|||
|
},
|
|||
|
borders: {
|
|||
|
strokeColor: 'black',
|
|||
|
highlightStrokeColor: 'gray'
|
|||
|
}
|
|||
|
}
|
|||
|
);
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
<!-- mixing coordinates and Point3D elements -->
|
|||
|
<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(
|
|||
|
'polygon-mixed-board',
|
|||
|
{
|
|||
|
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},
|
|||
|
depthOrderPoints: true
|
|||
|
}
|
|||
|
);
|
|||
|
|
|||
|
// create a list of individually styled Point3D elements to use as some
|
|||
|
// vertices of a polygon
|
|||
|
let vertices1 = [];
|
|||
|
coords1 = [
|
|||
|
[2, 1, 1],
|
|||
|
[2, 2, 1],
|
|||
|
[1, 2, 1],
|
|||
|
[1, 2, 2],
|
|||
|
[1, 1, 2],
|
|||
|
[1, 1, 1]
|
|||
|
];
|
|||
|
colors1 = [
|
|||
|
'orangered',
|
|||
|
'gold',
|
|||
|
'mediumseagreen',
|
|||
|
'darkturquoise',
|
|||
|
'purple',
|
|||
|
'deeppink'
|
|||
|
];
|
|||
|
for (i in coords1) {
|
|||
|
vertices1.push(view.create(
|
|||
|
'point3d',
|
|||
|
coords1[i],
|
|||
|
{
|
|||
|
withLabel: false,
|
|||
|
size: 5,
|
|||
|
strokeColor: 'none',
|
|||
|
fillColor: 'white',
|
|||
|
gradientSecondColor: colors1[i],
|
|||
|
highlightStrokeWidth: 1,
|
|||
|
highlightStrokeColor: '#777'
|
|||
|
}
|
|||
|
));
|
|||
|
}
|
|||
|
|
|||
|
// list the coordinates of the other vertices of the polygon
|
|||
|
let coords2 = [
|
|||
|
[0.5, 1.5, 1.5],
|
|||
|
[1.5, 1.5, 1.5],
|
|||
|
[1.5, 2.5, 1.5],
|
|||
|
[0.5, 2.5, 1.5]
|
|||
|
];
|
|||
|
|
|||
|
// create a polygon from a list of vertices (some given in coordinates, and
|
|||
|
// others given as Point3D elements)
|
|||
|
let polygon = view.create(
|
|||
|
'polygon3d',
|
|||
|
vertices1.slice(0, 3).concat(coords2, vertices1.slice(3, 6)),
|
|||
|
{
|
|||
|
vertices: {
|
|||
|
withLabel: false,
|
|||
|
strokeColor: 'none',
|
|||
|
fillColor: 'white',
|
|||
|
gradientSecondColor: '#444',
|
|||
|
highlightStrokeWidth: 1,
|
|||
|
highlightStrokeColor: 'black'
|
|||
|
},
|
|||
|
borders: {
|
|||
|
strokeColor: 'black',
|
|||
|
highlightStrokeColor: 'gray'
|
|||
|
}
|
|||
|
}
|
|||
|
);
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
<!-- filling a polygon -->
|
|||
|
<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(
|
|||
|
'planar-fill-board',
|
|||
|
{
|
|||
|
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},
|
|||
|
depthOrderPoints: true
|
|||
|
}
|
|||
|
);
|
|||
|
|
|||
|
// create a list of individually styled Point3D elements to use as polygon
|
|||
|
// vertices
|
|||
|
let vertices = [];
|
|||
|
coords = [
|
|||
|
[2, 0.5, 0.5],
|
|||
|
[0.5, 2, 0.5],
|
|||
|
[0.5, 0.5, 2],
|
|||
|
[0.5, 1.25, 1.25],
|
|||
|
[1.25, 0.5, 1.25],
|
|||
|
[1.25, 1.25, 0.5]
|
|||
|
];
|
|||
|
colors = [
|
|||
|
'#f08',
|
|||
|
'#fb0',
|
|||
|
'#0af',
|
|||
|
'#4f0',
|
|||
|
'#80f',
|
|||
|
'#f60'
|
|||
|
];
|
|||
|
for (i in coords) {
|
|||
|
vertices.push(view.create(
|
|||
|
'point3d',
|
|||
|
coords[i],
|
|||
|
{
|
|||
|
withLabel: false,
|
|||
|
size: 5,
|
|||
|
strokeColor: 'none',
|
|||
|
fillColor: 'white',
|
|||
|
gradientSecondColor: colors[i],
|
|||
|
highlightStrokeWidth: 1,
|
|||
|
highlightStrokeColor: '#777'
|
|||
|
}
|
|||
|
));
|
|||
|
}
|
|||
|
|
|||
|
// create some filled triangles
|
|||
|
view.create(
|
|||
|
'polygon3d',
|
|||
|
[vertices[0], vertices[5], vertices[4]],
|
|||
|
{
|
|||
|
fillColor: '#f85',
|
|||
|
fillOpacity: 0.4,
|
|||
|
borders: {strokeColor: 'none'}
|
|||
|
}
|
|||
|
);
|
|||
|
view.create(
|
|||
|
'polygon3d',
|
|||
|
[vertices[1], vertices[3], vertices[5]],
|
|||
|
{
|
|||
|
fillColor: '#af0',
|
|||
|
fillOpacity: 0.4,
|
|||
|
borders: {strokeColor: 'none'}
|
|||
|
}
|
|||
|
);
|
|||
|
view.create(
|
|||
|
'polygon3d',
|
|||
|
[vertices[2], vertices[3], vertices[4]],
|
|||
|
{
|
|||
|
fillColor: '#64f',
|
|||
|
fillOpacity: 0.4,
|
|||
|
borders: {strokeColor: 'none'}
|
|||
|
}
|
|||
|
);
|
|||
|
view.create(
|
|||
|
'polygon3d',
|
|||
|
[vertices[3], vertices[4], vertices[5]],
|
|||
|
{
|
|||
|
fillColor: '#a87',
|
|||
|
fillOpacity: 0.4,
|
|||
|
borders: {strokeColor: 'none'}
|
|||
|
}
|
|||
|
);
|
|||
|
|
|||
|
}
|
|||
|
</script>
|
|||
|
|
|||
|
<!-- the pitfalls of filling a non-planar polygon -->
|
|||
|
<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(
|
|||
|
'non-planar-fill-board',
|
|||
|
{
|
|||
|
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},
|
|||
|
depthOrderPoints: true
|
|||
|
}
|
|||
|
);
|
|||
|
|
|||
|
// create a list of individually styled Point3D elements to use as polygon
|
|||
|
// vertices
|
|||
|
let vertices = [];
|
|||
|
coords = [
|
|||
|
[2, 0.5, 0.5],
|
|||
|
[0.5, 2, 0.5],
|
|||
|
[0.5, 0.5, 2],
|
|||
|
[0.5, 1.25, 1.25],
|
|||
|
[1.25, 0.5, 1.25],
|
|||
|
[1.25, 1.25, 0.5]
|
|||
|
];
|
|||
|
colors = [
|
|||
|
'#f08',
|
|||
|
'#fb0',
|
|||
|
'#0af',
|
|||
|
'#4f0',
|
|||
|
'#80f',
|
|||
|
'#f60'
|
|||
|
];
|
|||
|
for (i in coords) {
|
|||
|
vertices.push(view.create(
|
|||
|
'point3d',
|
|||
|
coords[i],
|
|||
|
{
|
|||
|
withLabel: false,
|
|||
|
size: 5,
|
|||
|
strokeColor: 'none',
|
|||
|
fillColor: 'white',
|
|||
|
gradientSecondColor: colors[i],
|
|||
|
highlightStrokeWidth: 1,
|
|||
|
highlightStrokeColor: '#777'
|
|||
|
}
|
|||
|
));
|
|||
|
}
|
|||
|
|
|||
|
// create a filled polygon that can become non-planar
|
|||
|
view.create(
|
|||
|
'polygon3d',
|
|||
|
[vertices[0], vertices[5], vertices[1], vertices[3], vertices[2], vertices[4]],
|
|||
|
{
|
|||
|
fillColor: '#a87',
|
|||
|
fillOpacity: 0.4,
|
|||
|
borders: {strokeColor: 'none'}
|
|||
|
}
|
|||
|
);
|
|||
|
|
|||
|
}
|
|||
|
</script>
|
|||
|
</body>
|
|||
|
</html>
|