<!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>