1 /* 2 Copyright 2008-2024 3 Matthias Ehmann, 4 Aaron Fenyes, 5 Carsten Miller, 6 Andreas Walter, 7 Alfred Wassermann 8 9 This file is part of JSXGraph. 10 11 JSXGraph is free software dual licensed under the GNU LGPL or MIT License. 12 13 You can redistribute it and/or modify it under the terms of the 14 15 * GNU Lesser General Public License as published by 16 the Free Software Foundation, either version 3 of the License, or 17 (at your option) any later version 18 OR 19 * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT 20 21 JSXGraph is distributed in the hope that it will be useful, 22 but WITHOUT ANY WARRANTY; without even the implied warranty of 23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 GNU Lesser General Public License for more details. 25 26 You should have received a copy of the GNU Lesser General Public License and 27 the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/> 28 and <https://opensource.org/licenses/MIT/>. 29 */ 30 /*global JXG:true, define: true*/ 31 32 import JXG from '../jxg.js'; 33 import Const from '../base/constants.js'; 34 import Type from '../utils/type.js'; 35 36 // ----------------------- 37 // Lines 38 // ----------------------- 39 40 /** 41 * Constructor for 3D polygons. 42 * @class Creates a new 3D polygon object. Do not use this constructor to create a 3D polygon. Use {@link JXG.View3D#create} with type {@link Polygon3D} instead. 43 * 44 * @augments JXG.GeometryElement3D 45 * @augments JXG.GeometryElement 46 * @param {View3D} view 47 * @param {Point3D|Array} point 48 * @param {Array} direction 49 * @param {Array} range 50 * @param {Object} attributes 51 * @see JXG.Board#generateName 52 */ 53 JXG.Polygon3D = function (view, vertices, attributes) { 54 var i; 55 56 this.constructor(view.board, attributes, Const.OBJECT_TYPE_POLYGON3D, Const.OBJECT_CLASS_3D); 57 this.constructor3D(view, 'polygon3d'); 58 59 this.board.finalizeAdding(this); 60 61 /** 62 * References to the points defining the polygon. The last vertex is the same as the first vertex. 63 * @type Array 64 */ 65 this.vertices = []; 66 for (i = 0; i < vertices.length; i++) { 67 this.vertices[i] = this.board.select(vertices[i]); 68 69 // The _is_new flag is replaced by _is_new_pol. 70 // Otherwise, the polygon would disappear if the last border element 71 // is removed (and the point has been provided by coordinates) 72 if (this.vertices[i]._is_new) { 73 delete this.vertices[i]._is_new; 74 this.vertices[i]._is_new_pol = true; 75 } 76 } 77 }; 78 JXG.Polygon3D.prototype = new JXG.GeometryElement(); 79 Type.copyPrototypeMethods(JXG.Polygon3D, JXG.GeometryElement3D, 'constructor3D'); 80 81 JXG.extend( 82 JXG.Polygon3D.prototype, 83 /** @lends JXG.Polygon3D.prototype */ { 84 update: function () { 85 return this; 86 }, 87 88 updateRenderer: function () { 89 this.needsUpdate = false; 90 return this; 91 } 92 } 93 ); 94 95 /** 96 * @class A polygon is a sequence of points connected by lines, with the last point 97 * connecting back to the first one. The points are given by: 98 * <ul> 99 * <li> a list of Point3D objects, 100 * <li> a list of coordinate arrays, or 101 * <li> a function returning a list of coordinate arrays. 102 * </ul> 103 * Each two consecutive points of the list define a line. 104 * @pseudo 105 * @constructor 106 * @name Polygon 107 * @type JXG.Polygon 108 * @augments JXG.Polygon 109 * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown. 110 * @param {Array} vertices The polygon's vertices. If the first and the last vertex don't match the first one will be 111 * added to the array by the creator. Here, two points match if they have the same 'id' attribute. 112 */ 113 JXG.createPolygon3D = function (board, parents, attributes) { 114 var view = parents[0], 115 el, i, le, obj, 116 points = [], 117 points2d = [], 118 attr, 119 attr_points, 120 is_transform = false; 121 122 attr = Type.copyAttributes(attributes, board.options, 'polygon3d'); 123 obj = board.select(parents[1]); 124 if (obj === null) { 125 // This is necessary if the original polygon is defined in another board. 126 obj = parents[1]; 127 } 128 if ( 129 Type.isObject(obj) && 130 obj.type === Const.OBJECT_TYPE_POLYGON3D && 131 Type.isTransformationOrArray(parents[2]) 132 ) { 133 is_transform = true; 134 le = obj.vertices.length - 1; 135 attr_points = Type.copyAttributes(attributes, board.options, 'polygon3d', 'vertices'); 136 for (i = 0; i < le; i++) { 137 if (attr_points.withlabel) { 138 attr_points.name = 139 obj.vertices[i].name === '' ? '' : obj.vertices[i].name + "'"; 140 } 141 points.push(board.create('point3d', [obj.vertices[i], parents[2]], attr_points)); 142 } 143 } else { 144 points = Type.providePoints3D(view, parents.slice(1), attributes, 'polygon3d', ['vertices']); 145 if (points === false) { 146 throw new Error( 147 "JSXGraph: Can't create polygon3d with parent types other than 'point' and 'coordinate arrays' or a function returning an array of coordinates. Alternatively, a polygon3d and a transformation can be supplied" 148 ); 149 } 150 } 151 152 el = new JXG.Polygon3D(view, points, attr); 153 el.isDraggable = true; 154 155 attr = el.setAttr2D(attr); 156 for (i = 0; i < points.length; i++) { 157 points2d.push(points[i].element2D); 158 } 159 el.element2D = board.create('polygon', points2d, attr); 160 el.element2D.view = view; 161 el.addChild(el.element2D); 162 el.inherits.push(el.element2D); 163 el.element2D.setParents(el); 164 165 // Put the points in their positions 166 if (is_transform) { 167 el.prepareUpdate().update().updateVisibility().updateRenderer(); 168 le = obj.vertices.length - 1; 169 for (i = 0; i < le; i++) { 170 points[i].prepareUpdate().update().updateVisibility().updateRenderer(); 171 } 172 } 173 174 return el; 175 }; 176 JXG.registerElement('polygon3d', JXG.createPolygon3D);