1 /*
  2     Copyright 2008-2023
  3         Matthias Ehmann,
  4         Michael Gerhaeuser,
  5         Carsten Miller,
  6         Bianca Valentin,
  7         Alfred Wassermann,
  8         Peter Wilfahrt
  9 
 10     This file is part of JSXGraph.
 11 
 12     JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
 13 
 14     You can redistribute it and/or modify it under the terms of the
 15 
 16       * GNU Lesser General Public License as published by
 17         the Free Software Foundation, either version 3 of the License, or
 18         (at your option) any later version
 19       OR
 20       * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
 21 
 22     JSXGraph is distributed in the hope that it will be useful,
 23     but WITHOUT ANY WARRANTY; without even the implied warranty of
 24     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 25     GNU Lesser General Public License for more details.
 26 
 27     You should have received a copy of the GNU Lesser General Public License and
 28     the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>
 29     and <https://opensource.org/licenses/MIT/>.
 30  */
 31 
 32 /*global JXG: true, define: true*/
 33 /*jslint nomen: true, plusplus: true*/
 34 
 35 /**
 36  * @fileoverview In this file the geometry object Arc is defined. Arc stores all
 37  * style and functional properties that are required to draw an arc on a board.
 38  */
 39 
 40 import JXG from "../jxg";
 41 import Geometry from "../math/geometry";
 42 import Mat from "../math/math";
 43 import Coords from "../base/coords";
 44 import Circle from "../base/circle";
 45 import Type from "../utils/type";
 46 import Const from "../base/constants";
 47 
 48 /**
 49  * @class An arc is a segment of the circumference of a circle. It is defined by a center, one point that
 50  * defines the radius, and a third point that defines the angle of the arc.
 51  *
 52  * @pseudo
 53  * @name Arc
 54  * @augments Curve
 55  * @constructor
 56  * @type JXG.Curve
 57  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
 58  * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The result will be an arc of a circle around p1 through p2. The arc is drawn
 59  * counter-clockwise from p2 to p3.
 60  * @example
 61  * // Create an arc out of three free points
 62  * var p1 = board.create('point', [2.0, 2.0]);
 63  * var p2 = board.create('point', [1.0, 0.5]);
 64  * var p3 = board.create('point', [3.5, 1.0]);
 65  *
 66  * var a = board.create('arc', [p1, p2, p3]);
 67  * board.create('text',[1,6,function(){return 'arclength: '+Math.round(a.Value()*100)/100}])
 68  * </pre><div class="jxgbox" id="JXG114ef584-4a5e-4686-8392-c97501befb5b" style="width: 300px; height: 300px;"></div>
 69  * <script type="text/javascript">
 70  * (function () {
 71  *   var board = JXG.JSXGraph.initBoard('JXG114ef584-4a5e-4686-8392-c97501befb5b', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
 72  *       p1 = board.create('point', [2.0, 2.0]),
 73  *       p2 = board.create('point', [1.0, 0.5]),
 74  *       p3 = board.create('point', [3.5, 1.0]),
 75  *
 76  *       a = board.create('arc', [p1, p2, p3]);
 77  *       board.create('text',[1,6,function(){return 'arclength: '+Math.round(a.Value()*100)/100}])
 78  * })();
 79  * </script><pre>
 80  *
 81  * @example
 82  * var t = board.create('transform', [2, 1.5], {type: 'scale'});
 83  * var a1 = board.create('arc', [[1, 1], [0, 1], [1, 0]], {strokeColor: 'red'});
 84  * var a2 = board.create('curve', [a1, t], {strokeColor: 'red'});
 85  *
 86  * </pre><div id="JXG1949da46-6339-11e8-9fb9-901b0e1b8723" class="jxgbox" style="width: 300px; height: 300px;"></div>
 87  * <script type="text/javascript">
 88  *     (function() {
 89  *         var board = JXG.JSXGraph.initBoard('JXG1949da46-6339-11e8-9fb9-901b0e1b8723',
 90  *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
 91  *     var t = board.create('transform', [2, 1.5], {type: 'scale'});
 92  *     var a1 = board.create('arc', [[1, 1], [0, 1], [1, 0]], {strokeColor: 'red'});
 93  *     var a2 = board.create('curve', [a1, t], {strokeColor: 'red'});
 94  *
 95  *     })();
 96  *
 97  * </script><pre>
 98  *
 99  */
100 JXG.createArc = function (board, parents, attributes) {
101     var el, attr, points;
102 
103     points = Type.providePoints(board, parents, attributes, "arc", [
104         "center",
105         "radiusPoint",
106         "anglePoint"
107     ]);
108     if (points === false || points.length < 3) {
109         throw new Error(
110             "JSXGraph: Can't create Arc with parent types '" +
111                 typeof parents[0] +
112                 "' and '" +
113                 typeof parents[1] +
114                 "' and '" +
115                 typeof parents[2] +
116                 "'." +
117                 "\nPossible parent types: [point,point,point], [arc, transformation]"
118         );
119     }
120 
121     attr = Type.copyAttributes(attributes, board.options, "arc");
122     el = board.create("curve", [[0], [0]], attr);
123 
124     el.elType = "arc";
125     el.setParents(points);
126 
127     /**
128      * documented in JXG.GeometryElement
129      * @ignore
130      */
131     el.type = Const.OBJECT_TYPE_ARC;
132 
133     /**
134      * Center of the arc.
135      * @memberOf Arc.prototype
136      * @name center
137      * @type JXG.Point
138      */
139     el.center = points[0];
140 
141     /**
142      * Point defining the arc's radius.
143      * @memberOf Arc.prototype
144      * @name radiuspoint
145      * @type JXG.Point
146      */
147     el.radiuspoint = points[1];
148     el.point2 = el.radiuspoint;
149 
150     /**
151      * The point defining the arc's angle.
152      * @memberOf Arc.prototype
153      * @name anglepoint
154      * @type JXG.Point
155      */
156     el.anglepoint = points[2];
157     el.point3 = el.anglepoint;
158 
159     // Add arc as child to defining points
160     // or vice versa if the points are provided as coordinates
161     if (Type.exists(el.center._is_new)) {
162         el.addChild(el.center);
163         delete el.center._is_new;
164     } else {
165         el.center.addChild(el);
166     }
167     if (Type.exists(el.radiuspoint._is_new)) {
168         el.addChild(el.radiuspoint);
169         delete el.radiuspoint._is_new;
170     } else {
171         el.radiuspoint.addChild(el);
172     }
173     if (Type.exists(el.anglepoint._is_new)) {
174         el.addChild(el.anglepoint);
175         delete el.anglepoint._is_new;
176     } else {
177         el.anglepoint.addChild(el);
178     }
179 
180     // should be documented in options
181     el.useDirection = attr.usedirection;
182 
183     // documented in JXG.Curve
184     el.updateDataArray = function () {
185         var ar,
186             phi,
187             det,
188             p0c,
189             p1c,
190             p2c,
191             sgn = 1,
192             A = this.radiuspoint,
193             B = this.center,
194             C = this.anglepoint,
195             ev_s = Type.evaluate(this.visProp.selection);
196 
197         phi = Geometry.rad(A, B, C);
198         if ((ev_s === "minor" && phi > Math.PI) || (ev_s === "major" && phi < Math.PI)) {
199             sgn = -1;
200         }
201 
202         // This is true for circumCircleArcs. In that case there is
203         // a fourth parent element: [center, point1, point3, point2]
204         if (this.useDirection) {
205             p0c = points[1].coords.usrCoords;
206             p1c = points[3].coords.usrCoords;
207             p2c = points[2].coords.usrCoords;
208             det = (p0c[1] - p2c[1]) * (p0c[2] - p1c[2]) - (p0c[2] - p2c[2]) * (p0c[1] - p1c[1]);
209 
210             if (det < 0) {
211                 this.radiuspoint = points[1];
212                 this.anglepoint = points[2];
213             } else {
214                 this.radiuspoint = points[2];
215                 this.anglepoint = points[1];
216             }
217         }
218 
219         A = A.coords.usrCoords;
220         B = B.coords.usrCoords;
221         C = C.coords.usrCoords;
222 
223         ar = Geometry.bezierArc(A, B, C, false, sgn);
224 
225         this.dataX = ar[0];
226         this.dataY = ar[1];
227 
228         this.bezierDegree = 3;
229 
230         this.updateStdform();
231         this.updateQuadraticform();
232     };
233 
234     /**
235      * Determines the arc's current radius. I.e. the distance between {@link Arc#center} and {@link Arc#radiuspoint}.
236      * @memberOf Arc.prototype
237      * @name Radius
238      * @function
239      * @returns {Number} The arc's radius
240      */
241     el.Radius = function () {
242         return this.radiuspoint.Dist(this.center);
243     };
244 
245     /**
246      * @deprecated Use {@link Arc#Radius}
247      * @memberOf Arc.prototype
248      * @name getRadius
249      * @function
250      * @returns {Number}
251      */
252     el.getRadius = function () {
253         JXG.deprecated("Arc.getRadius()", "Arc.Radius()");
254         return this.Radius();
255     };
256 
257     /**
258      * Returns the length of the arc.
259      * @memberOf Arc.prototype
260      * @name Value
261      * @function
262      * @returns {Number} The arc length
263      */
264     el.Value = function () {
265         return this.Radius() * Geometry.rad(this.radiuspoint, this.center, this.anglepoint);
266     };
267 
268     // documented in geometry element
269     el.hasPoint = function (x, y) {
270         var dist,
271             checkPoint,
272             has,
273             invMat,
274             c,
275             prec,
276             type,
277             r = this.Radius();
278 
279         if (Type.evaluate(this.visProp.hasinnerpoints)) {
280             return this.hasPointSector(x, y);
281         }
282 
283         if (Type.isObject(Type.evaluate(this.visProp.precision))) {
284             type = this.board._inputDevice;
285             prec = Type.evaluate(this.visProp.precision[type]);
286         } else {
287             // 'inherit'
288             prec = this.board.options.precision.hasPoint;
289         }
290         prec /= Math.min(Math.abs(this.board.unitX), Math.abs(this.board.unitY));
291         checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board);
292 
293         if (this.transformations.length > 0) {
294             // Transform the mouse/touch coordinates
295             // back to the original position of the curve.
296             this.updateTransformMatrix();
297             invMat = Mat.inverse(this.transformMat);
298             c = Mat.matVecMult(invMat, checkPoint.usrCoords);
299             checkPoint = new Coords(Const.COORDS_BY_USER, c, this.board);
300         }
301 
302         dist = this.center.coords.distance(Const.COORDS_BY_USER, checkPoint);
303         has = Math.abs(dist - r) < prec;
304 
305         /**
306          * At that point we know that the user has touched the circle line.
307          * Now, we have to check, if the user has hit the arc path.
308          */
309         if (has) {
310             has = Geometry.coordsOnArc(this, checkPoint);
311         }
312         return has;
313     };
314 
315     /**
316      * Checks whether (x,y) is within the sector defined by the arc.
317      * @memberOf Arc.prototype
318      * @name hasPointSector
319      * @function
320      * @param {Number} x Coordinate in x direction, screen coordinates.
321      * @param {Number} y Coordinate in y direction, screen coordinates.
322      * @returns {Boolean} True if (x,y) is within the sector defined by the arc, False otherwise.
323      */
324     el.hasPointSector = function (x, y) {
325         var checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board),
326             r = this.Radius(),
327             dist = this.center.coords.distance(Const.COORDS_BY_USER, checkPoint),
328             has = dist < r;
329 
330         if (has) {
331             has = Geometry.coordsOnArc(this, checkPoint);
332         }
333         return has;
334     };
335 
336     // documented in geometry element
337     el.getTextAnchor = function () {
338         return this.center.coords;
339     };
340 
341     // documented in geometry element
342     el.getLabelAnchor = function () {
343         var coords,
344             vec,
345             vecx,
346             vecy,
347             len,
348             angle = Geometry.rad(this.radiuspoint, this.center, this.anglepoint),
349             dx = 10 / this.board.unitX,
350             dy = 10 / this.board.unitY,
351             p2c = this.point2.coords.usrCoords,
352             pmc = this.center.coords.usrCoords,
353             bxminusax = p2c[1] - pmc[1],
354             byminusay = p2c[2] - pmc[2],
355             ev_s = Type.evaluate(this.visProp.selection),
356             l_vp = this.label ? this.label.visProp : this.visProp.label;
357 
358         // If this is uncommented, the angle label can not be dragged
359         //if (Type.exists(this.label)) {
360         //    this.label.relativeCoords = new Coords(Const.COORDS_BY_SCREEN, [0, 0], this.board);
361         //}
362 
363         if ((ev_s === "minor" && angle > Math.PI) || (ev_s === "major" && angle < Math.PI)) {
364             angle = -(2 * Math.PI - angle);
365         }
366 
367         coords = new Coords(
368             Const.COORDS_BY_USER,
369             [
370                 pmc[1] + Math.cos(angle * 0.5) * bxminusax - Math.sin(angle * 0.5) * byminusay,
371                 pmc[2] + Math.sin(angle * 0.5) * bxminusax + Math.cos(angle * 0.5) * byminusay
372             ],
373             this.board
374         );
375 
376         vecx = coords.usrCoords[1] - pmc[1];
377         vecy = coords.usrCoords[2] - pmc[2];
378 
379         len = Math.sqrt(vecx * vecx + vecy * vecy);
380         vecx = (vecx * (len + dx)) / len;
381         vecy = (vecy * (len + dy)) / len;
382         vec = [pmc[1] + vecx, pmc[2] + vecy];
383 
384         l_vp.position = Geometry.calcLabelQuadrant(Geometry.rad([1, 0], [0, 0], vec));
385 
386         return new Coords(Const.COORDS_BY_USER, vec, this.board);
387     };
388 
389     // documentation in jxg.circle
390     el.updateQuadraticform = Circle.prototype.updateQuadraticform;
391 
392     // documentation in jxg.circle
393     el.updateStdform = Circle.prototype.updateStdform;
394 
395     el.methodMap = JXG.deepCopy(el.methodMap, {
396         getRadius: "getRadius",
397         radius: "Radius",
398         center: "center",
399         radiuspoint: "radiuspoint",
400         anglepoint: "anglepoint",
401         Value: "Value"
402     });
403 
404     el.prepareUpdate().update();
405     return el;
406 };
407 
408 JXG.registerElement("arc", JXG.createArc);
409 
410 /**
411  * @class A semicircle is a special arc defined by two points. The arc hits both points.
412  * @pseudo
413  * @name Semicircle
414  * @augments Arc
415  * @constructor
416  * @type Arc
417  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
418  * @param {JXG.Point_JXG.Point} p1,p2 The result will be a composition of an arc drawn clockwise from <tt>p1</tt> and
419  * <tt>p2</tt> and the midpoint of <tt>p1</tt> and <tt>p2</tt>.
420  * @example
421  * // Create an arc out of three free points
422  * var p1 = board.create('point', [4.5, 2.0]);
423  * var p2 = board.create('point', [1.0, 0.5]);
424  *
425  * var a = board.create('semicircle', [p1, p2]);
426  * </pre><div class="jxgbox" id="JXG5385d349-75d7-4078-b732-9ae808db1b0e" style="width: 300px; height: 300px;"></div>
427  * <script type="text/javascript">
428  * (function () {
429  *   var board = JXG.JSXGraph.initBoard('JXG5385d349-75d7-4078-b732-9ae808db1b0e', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
430  *       p1 = board.create('point', [4.5, 2.0]),
431  *       p2 = board.create('point', [1.0, 0.5]),
432  *
433  *       sc = board.create('semicircle', [p1, p2]);
434  * })();
435  * </script><pre>
436  */
437 JXG.createSemicircle = function (board, parents, attributes) {
438     var el, mp, attr, points;
439 
440     // we need 2 points
441     points = Type.providePoints(board, parents, attributes, "point");
442     if (points === false || points.length !== 2) {
443         throw new Error(
444             "JSXGraph: Can't create Semicircle with parent types '" +
445                 typeof parents[0] +
446                 "' and '" +
447                 typeof parents[1] +
448                 "'." +
449                 "\nPossible parent types: [point,point]"
450         );
451     }
452 
453     attr = Type.copyAttributes(attributes, board.options, "semicircle", "center");
454     mp = board.create("midpoint", points, attr);
455     mp.dump = false;
456 
457     attr = Type.copyAttributes(attributes, board.options, "semicircle");
458     el = board.create("arc", [mp, points[1], points[0]], attr);
459     el.elType = "semicircle";
460     el.setParents([points[0].id, points[1].id]);
461     el.subs = {
462         midpoint: mp
463     };
464     el.inherits.push(mp);
465 
466     /**
467      * The midpoint of the two defining points.
468      * @memberOf Semicircle.prototype
469      * @name midpoint
470      * @type Midpoint
471      */
472     el.midpoint = el.center = mp;
473 
474     return el;
475 };
476 
477 JXG.registerElement("semicircle", JXG.createSemicircle);
478 
479 /**
480  * @class A circumcircle arc is an {@link Arc} defined by three points. All three points lie on the arc.
481  * @pseudo
482  * @name CircumcircleArc
483  * @augments Arc
484  * @constructor
485  * @type Arc
486  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
487  * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The result will be a composition of an arc of the circumcircle of
488  * <tt>p1</tt>, <tt>p2</tt>, and <tt>p3</tt> and the midpoint of the circumcircle of the three points. The arc is drawn
489  * counter-clockwise from <tt>p1</tt> over <tt>p2</tt> to <tt>p3</tt>.
490  * @example
491  * // Create a circum circle arc out of three free points
492  * var p1 = board.create('point', [2.0, 2.0]);
493  * var p2 = board.create('point', [1.0, 0.5]);
494  * var p3 = board.create('point', [3.5, 1.0]);
495  *
496  * var a = board.create('circumcirclearc', [p1, p2, p3]);
497  * </pre><div class="jxgbox" id="JXG87125fd4-823a-41c1-88ef-d1a1369504e3" style="width: 300px; height: 300px;"></div>
498  * <script type="text/javascript">
499  * (function () {
500  *   var board = JXG.JSXGraph.initBoard('JXG87125fd4-823a-41c1-88ef-d1a1369504e3', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
501  *       p1 = board.create('point', [2.0, 2.0]),
502  *       p2 = board.create('point', [1.0, 0.5]),
503  *       p3 = board.create('point', [3.5, 1.0]),
504  *
505  *       cca = board.create('circumcirclearc', [p1, p2, p3]);
506  * })();
507  * </script><pre>
508  */
509 JXG.createCircumcircleArc = function (board, parents, attributes) {
510     var el, mp, attr, points;
511 
512     // We need three points
513     points = Type.providePoints(board, parents, attributes, "point");
514     if (points === false || points.length !== 3) {
515         throw new Error(
516             "JSXGraph: create Circumcircle Arc with parent types '" +
517                 typeof parents[0] +
518                 "' and '" +
519                 typeof parents[1] +
520                 "' and '" +
521                 typeof parents[2] +
522                 "'." +
523                 "\nPossible parent types: [point,point,point]"
524         );
525     }
526 
527     attr = Type.copyAttributes(attributes, board.options, "circumcirclearc", "center");
528     mp = board.create("circumcenter", points, attr);
529     mp.dump = false;
530 
531     attr = Type.copyAttributes(attributes, board.options, "circumcirclearc");
532     attr.usedirection = true;
533     el = board.create("arc", [mp, points[0], points[2], points[1]], attr);
534 
535     el.elType = "circumcirclearc";
536     el.setParents([points[0].id, points[1].id, points[2].id]);
537     el.subs = {
538         center: mp
539     };
540     el.inherits.push(mp);
541 
542     /**
543      * The midpoint of the circumcircle of the three points defining the circumcircle arc.
544      * @memberOf CircumcircleArc.prototype
545      * @name center
546      * @type Circumcenter
547      */
548     el.center = mp;
549 
550     return el;
551 };
552 
553 JXG.registerElement("circumcirclearc", JXG.createCircumcircleArc);
554 
555 /**
556  * @class A minor arc is a segment of the circumference of a circle having measure less than or equal to
557  * 180 degrees (pi radians). It is defined by a center, one point that
558  * defines the radius, and a third point that defines the angle of the arc.
559  * @pseudo
560  * @name MinorArc
561  * @augments Curve
562  * @constructor
563  * @type JXG.Curve
564  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
565  * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 . Minor arc is an arc of a circle around p1 having measure less than or equal to
566  * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3.
567  * @example
568  * // Create an arc out of three free points
569  * var p1 = board.create('point', [2.0, 2.0]);
570  * var p2 = board.create('point', [1.0, 0.5]);
571  * var p3 = board.create('point', [3.5, 1.0]);
572  *
573  * var a = board.create('arc', [p1, p2, p3]);
574  * </pre><div class="jxgbox" id="JXG64ba7ca2-8728-45f3-96e5-3c7a4414de2f" style="width: 300px; height: 300px;"></div>
575  * <script type="text/javascript">
576  * (function () {
577  *   var board = JXG.JSXGraph.initBoard('JXG64ba7ca2-8728-45f3-96e5-3c7a4414de2f', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
578  *       p1 = board.create('point', [2.0, 2.0]),
579  *       p2 = board.create('point', [1.0, 0.5]),
580  *       p3 = board.create('point', [3.5, 1.0]),
581  *
582  *       a = board.create('minorarc', [p1, p2, p3]);
583  * })();
584  * </script><pre>
585  */
586 
587 JXG.createMinorArc = function (board, parents, attributes) {
588     attributes.selection = "minor";
589     return JXG.createArc(board, parents, attributes);
590 };
591 
592 JXG.registerElement("minorarc", JXG.createMinorArc);
593 
594 /**
595  * @class A major arc is a segment of the circumference of a circle having measure greater than or equal to
596  * 180 degrees (pi radians). It is defined by a center, one point that
597  * defines the radius, and a third point that defines the angle of the arc.
598  * @pseudo
599  * @name MajorArc
600  * @augments Curve
601  * @constructor
602  * @type JXG.Curve
603  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
604  * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 . Major arc is an arc of a circle around p1 having measure greater than or equal to
605  * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3.
606  * @example
607  * // Create an arc out of three free points
608  * var p1 = board.create('point', [2.0, 2.0]);
609  * var p2 = board.create('point', [1.0, 0.5]);
610  * var p3 = board.create('point', [3.5, 1.0]);
611  *
612  * var a = board.create('majorarc', [p1, p2, p3]);
613  * </pre><div class="jxgbox" id="JXG17a10d38-5629-40a4-b150-f41806edee9f" style="width: 300px; height: 300px;"></div>
614  * <script type="text/javascript">
615  * (function () {
616  *   var board = JXG.JSXGraph.initBoard('JXG17a10d38-5629-40a4-b150-f41806edee9f', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
617  *       p1 = board.create('point', [2.0, 2.0]),
618  *       p2 = board.create('point', [1.0, 0.5]),
619  *       p3 = board.create('point', [3.5, 1.0]),
620  *
621  *       a = board.create('majorarc', [p1, p2, p3]);
622  * })();
623  * </script><pre>
624  */
625 JXG.createMajorArc = function (board, parents, attributes) {
626     attributes.selection = "major";
627     return JXG.createArc(board, parents, attributes);
628 };
629 
630 JXG.registerElement("majorarc", JXG.createMajorArc);
631 
632 // export default {
633 //     createArc: JXG.createArc,
634 //     createSemicircle: JXG.createSemicircle,
635 //     createCircumcircleArc: JXG.createCircumcircleArc,
636 //     createMinorArc: JXG.createMinorArc,
637 //     createMajorArc: JXG.createMajorArc
638 // };
639