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     // attributes.radiusPoint = {visible: false};
104     points = Type.providePoints(board, parents, attributes, "arc", [
105         "center",
106         "radiuspoint",
107         "anglepoint"
108     ]);
109     if (points === false || points.length < 3) {
110         throw new Error(
111             "JSXGraph: Can't create Arc with parent types '" +
112                 typeof parents[0] +
113                 "' and '" +
114                 typeof parents[1] +
115                 "' and '" +
116                 typeof parents[2] +
117                 "'." +
118                 "\nPossible parent types: [point,point,point], [arc, transformation]"
119         );
120     }
121 
122     attr = Type.copyAttributes(attributes, board.options, "arc");
123     el = board.create("curve", [[0], [0]], attr);
124 
125     el.elType = "arc";
126     el.setParents(points);
127 
128     /**
129      * documented in JXG.GeometryElement
130      * @ignore
131      */
132     el.type = Const.OBJECT_TYPE_ARC;
133 
134     /**
135      * Center of the arc.
136      * @memberOf Arc.prototype
137      * @name center
138      * @type JXG.Point
139      */
140     el.center = points[0];
141 
142     /**
143      * Point defining the arc's radius.
144      * @memberOf Arc.prototype
145      * @name radiuspoint
146      * @type JXG.Point
147      */
148     el.radiuspoint = points[1];
149     el.point2 = el.radiuspoint;
150 
151     /**
152      * The point defining the arc's angle.
153      * @memberOf Arc.prototype
154      * @name anglepoint
155      * @type JXG.Point
156      */
157     el.anglepoint = points[2];
158     el.point3 = el.anglepoint;
159 
160     // Add arc as child to defining points
161     // or vice versa if the points are provided as coordinates
162     if (Type.exists(el.center._is_new)) {
163         el.addChild(el.center);
164         delete el.center._is_new;
165     } else {
166         el.center.addChild(el);
167     }
168     if (Type.exists(el.radiuspoint._is_new)) {
169         el.addChild(el.radiuspoint);
170         delete el.radiuspoint._is_new;
171     } else {
172         el.radiuspoint.addChild(el);
173     }
174     if (Type.exists(el.anglepoint._is_new)) {
175         el.addChild(el.anglepoint);
176         delete el.anglepoint._is_new;
177     } else {
178         el.anglepoint.addChild(el);
179     }
180 
181     // should be documented in options
182     el.useDirection = attr.usedirection;
183 
184     // documented in JXG.Curve
185     /**
186      * @class
187      * @ignore
188      */
189     el.updateDataArray = function () {
190         var ar,
191             phi,
192             det,
193             p0c,
194             p1c,
195             p2c,
196             sgn = 1,
197             A = this.radiuspoint,
198             B = this.center,
199             C = this.anglepoint,
200             ev_s = Type.evaluate(this.visProp.selection);
201 
202         phi = Geometry.rad(A, B, C);
203         if ((ev_s === "minor" && phi > Math.PI) || (ev_s === "major" && phi < Math.PI)) {
204             sgn = -1;
205         }
206 
207         // This is true for circumCircleArcs. In that case there is
208         // a fourth parent element: [center, point1, point3, point2]
209         if (this.useDirection) {
210             p0c = points[1].coords.usrCoords;
211             p1c = points[3].coords.usrCoords;
212             p2c = points[2].coords.usrCoords;
213             det = (p0c[1] - p2c[1]) * (p0c[2] - p1c[2]) - (p0c[2] - p2c[2]) * (p0c[1] - p1c[1]);
214 
215             if (det < 0) {
216                 this.radiuspoint = points[1];
217                 this.anglepoint = points[2];
218             } else {
219                 this.radiuspoint = points[2];
220                 this.anglepoint = points[1];
221             }
222         }
223 
224         A = A.coords.usrCoords;
225         B = B.coords.usrCoords;
226         C = C.coords.usrCoords;
227 
228         ar = Geometry.bezierArc(A, B, C, false, sgn);
229 
230         this.dataX = ar[0];
231         this.dataY = ar[1];
232 
233         this.bezierDegree = 3;
234 
235         this.updateStdform();
236         this.updateQuadraticform();
237     };
238 
239     /**
240      * Determines the arc's current radius. I.e. the distance between {@link Arc#center} and {@link Arc#radiuspoint}.
241      * @memberOf Arc.prototype
242      * @name Radius
243      * @function
244      * @returns {Number} The arc's radius
245      */
246     el.Radius = function () {
247         return this.radiuspoint.Dist(this.center);
248     };
249 
250     /**
251      * @deprecated Use {@link Arc#Radius}
252      * @memberOf Arc.prototype
253      * @name getRadius
254      * @function
255      * @returns {Number}
256      */
257     el.getRadius = function () {
258         JXG.deprecated("Arc.getRadius()", "Arc.Radius()");
259         return this.Radius();
260     };
261 
262     /**
263      * Returns the length of the arc or the value of the angle spanned by the arc.
264      * @memberOf Arc.prototype
265      * @name Value
266      * @function
267      * @param {String} [unit='length'] Unit of the returned values. Possible units are
268      * <ul>
269      * <li> 'length' (default): length of the arc line
270      * <li> 'radians': angle spanned by the arc in radians
271      * <li> 'degrees': angle spanned by the arc in degrees
272      * <li> 'semicircle': angle spanned by the arc in radians as a multiple of π, e.g. if the angle is 1.5π, 1.5 will be returned.
273      * <li> 'circle': angle spanned by the arc in radians as a multiple of 2π
274      * </ul>
275      * It is sufficient to supply the first three characters of the unit, e.g. 'len'.
276      * @param {Number} [rad=undefined] Value of angle which can be used instead of the generic one.
277      * @returns {Number} The arc length or the angle value in various units.
278      */
279     el.Value = function (unit, rad) {
280         var val;
281 
282         rad = rad || Geometry.rad(this.radiuspoint, this.center, this.anglepoint);
283 
284         unit = unit || 'length';
285         unit = unit.toLocaleLowerCase();
286         if (unit === '' || unit.indexOf('len') === 0) {
287             val = rad * this.Radius();
288         } else if (unit.indexOf('rad') === 0) {
289             val = rad;
290         } else if (unit.indexOf('deg') === 0) {
291             val = rad * 180 / Math.PI;
292         } else if (unit.indexOf('sem') === 0) {
293             val = rad / Math.PI;
294         } else if (unit.indexOf('cir') === 0) {
295             val = rad * 0.5 / Math.PI;
296         }
297 
298         return val;
299     };
300 
301     /**
302      * Arc length.
303      * @memberOf Arc.prototype
304      * @name L
305      * @returns {Number} Length of the arc.
306      * @see Arc#Value
307      */
308     el.L = function() {
309         return this.Value('length');
310     };
311 
312     // documented in geometry element
313     el.hasPoint = function (x, y) {
314         var dist,
315             checkPoint,
316             has,
317             invMat,
318             c,
319             prec,
320             type,
321             r = this.Radius();
322 
323         if (Type.evaluate(this.visProp.hasinnerpoints)) {
324             return this.hasPointSector(x, y);
325         }
326 
327         if (Type.isObject(Type.evaluate(this.visProp.precision))) {
328             type = this.board._inputDevice;
329             prec = Type.evaluate(this.visProp.precision[type]);
330         } else {
331             // 'inherit'
332             prec = this.board.options.precision.hasPoint;
333         }
334         prec /= Math.min(Math.abs(this.board.unitX), Math.abs(this.board.unitY));
335         checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board);
336 
337         if (this.transformations.length > 0) {
338             // Transform the mouse/touch coordinates
339             // back to the original position of the curve.
340             this.updateTransformMatrix();
341             invMat = Mat.inverse(this.transformMat);
342             c = Mat.matVecMult(invMat, checkPoint.usrCoords);
343             checkPoint = new Coords(Const.COORDS_BY_USER, c, this.board);
344         }
345 
346         dist = this.center.coords.distance(Const.COORDS_BY_USER, checkPoint);
347         has = Math.abs(dist - r) < prec;
348 
349         /**
350          * At that point we know that the user has touched the circle line.
351          * Now, we have to check, if the user has hit the arc path.
352          */
353         if (has) {
354             has = Geometry.coordsOnArc(this, checkPoint);
355         }
356         return has;
357     };
358 
359     /**
360      * Checks whether (x,y) is within the sector defined by the arc.
361      * @memberOf Arc.prototype
362      * @name hasPointSector
363      * @function
364      * @param {Number} x Coordinate in x direction, screen coordinates.
365      * @param {Number} y Coordinate in y direction, screen coordinates.
366      * @returns {Boolean} True if (x,y) is within the sector defined by the arc, False otherwise.
367      */
368     el.hasPointSector = function (x, y) {
369         var checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board),
370             r = this.Radius(),
371             dist = this.center.coords.distance(Const.COORDS_BY_USER, checkPoint),
372             has = dist < r;
373 
374         if (has) {
375             has = Geometry.coordsOnArc(this, checkPoint);
376         }
377         return has;
378     };
379 
380     // documented in geometry element
381     el.getTextAnchor = function () {
382         return this.center.coords;
383     };
384 
385     // documented in geometry element
386     /**
387      * @class
388      * @ignore
389      */
390     el.getLabelAnchor = function () {
391         var coords,
392             vec,
393             vecx,
394             vecy,
395             len,
396             angle = Geometry.rad(this.radiuspoint, this.center, this.anglepoint),
397             dx = 10 / this.board.unitX,
398             dy = 10 / this.board.unitY,
399             p2c = this.point2.coords.usrCoords,
400             pmc = this.center.coords.usrCoords,
401             bxminusax = p2c[1] - pmc[1],
402             byminusay = p2c[2] - pmc[2],
403             ev_s = Type.evaluate(this.visProp.selection),
404             l_vp = this.label ? this.label.visProp : this.visProp.label;
405 
406         // If this is uncommented, the angle label can not be dragged
407         //if (Type.exists(this.label)) {
408         //    this.label.relativeCoords = new Coords(Const.COORDS_BY_SCREEN, [0, 0], this.board);
409         //}
410 
411         if ((ev_s === "minor" && angle > Math.PI) || (ev_s === "major" && angle < Math.PI)) {
412             angle = -(2 * Math.PI - angle);
413         }
414 
415         coords = new Coords(
416             Const.COORDS_BY_USER,
417             [
418                 pmc[1] + Math.cos(angle * 0.5) * bxminusax - Math.sin(angle * 0.5) * byminusay,
419                 pmc[2] + Math.sin(angle * 0.5) * bxminusax + Math.cos(angle * 0.5) * byminusay
420             ],
421             this.board
422         );
423 
424         vecx = coords.usrCoords[1] - pmc[1];
425         vecy = coords.usrCoords[2] - pmc[2];
426 
427         len = Mat.hypot(vecx, vecy);
428         vecx = (vecx * (len + dx)) / len;
429         vecy = (vecy * (len + dy)) / len;
430         vec = [pmc[1] + vecx, pmc[2] + vecy];
431 
432         l_vp.position = Geometry.calcLabelQuadrant(Geometry.rad([1, 0], [0, 0], vec));
433 
434         return new Coords(Const.COORDS_BY_USER, vec, this.board);
435     };
436 
437     // documentation in jxg.circle
438     el.updateQuadraticform = Circle.prototype.updateQuadraticform;
439 
440     // documentation in jxg.circle
441     el.updateStdform = Circle.prototype.updateStdform;
442 
443     el.methodMap = JXG.deepCopy(el.methodMap, {
444         getRadius: "getRadius",
445         radius: "Radius",
446         center: "center",
447         radiuspoint: "radiuspoint",
448         anglepoint: "anglepoint",
449         // Angle: "Angle",
450         // Rad: "Angle",
451         // Deg: "AngleDeg",
452         // PI: "AnglePI",
453         Value: "Value",
454         L: "L"
455     });
456 
457     el.prepareUpdate().update();
458     return el;
459 };
460 
461 JXG.registerElement("arc", JXG.createArc);
462 
463 /**
464  * @class A semicircle is a special arc defined by two points. The arc hits both points.
465  * @pseudo
466  * @name Semicircle
467  * @augments Arc
468  * @constructor
469  * @type Arc
470  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
471  * @param {JXG.Point_JXG.Point} p1,p2 The result will be a composition of an arc drawn clockwise from <tt>p1</tt> and
472  * <tt>p2</tt> and the midpoint of <tt>p1</tt> and <tt>p2</tt>.
473  * @example
474  * // Create an arc out of three free points
475  * var p1 = board.create('point', [4.5, 2.0]);
476  * var p2 = board.create('point', [1.0, 0.5]);
477  *
478  * var a = board.create('semicircle', [p1, p2]);
479  * </pre><div class="jxgbox" id="JXG5385d349-75d7-4078-b732-9ae808db1b0e" style="width: 300px; height: 300px;"></div>
480  * <script type="text/javascript">
481  * (function () {
482  *   var board = JXG.JSXGraph.initBoard('JXG5385d349-75d7-4078-b732-9ae808db1b0e', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
483  *       p1 = board.create('point', [4.5, 2.0]),
484  *       p2 = board.create('point', [1.0, 0.5]),
485  *
486  *       sc = board.create('semicircle', [p1, p2]);
487  * })();
488  * </script><pre>
489  */
490 JXG.createSemicircle = function (board, parents, attributes) {
491     var el, mp, attr, points;
492 
493     // we need 2 points
494     points = Type.providePoints(board, parents, attributes, "point");
495     if (points === false || points.length !== 2) {
496         throw new Error(
497             "JSXGraph: Can't create Semicircle with parent types '" +
498                 typeof parents[0] +
499                 "' and '" +
500                 typeof parents[1] +
501                 "'." +
502                 "\nPossible parent types: [point,point]"
503         );
504     }
505 
506     attr = Type.copyAttributes(attributes, board.options, "semicircle", "center");
507     mp = board.create("midpoint", points, attr);
508     mp.dump = false;
509 
510     attr = Type.copyAttributes(attributes, board.options, "semicircle");
511     el = board.create("arc", [mp, points[1], points[0]], attr);
512     el.elType = "semicircle";
513     el.setParents([points[0].id, points[1].id]);
514     el.subs = {
515         midpoint: mp
516     };
517     el.inherits.push(mp);
518 
519     /**
520      * The midpoint of the two defining points.
521      * @memberOf Semicircle.prototype
522      * @name midpoint
523      * @type Midpoint
524      */
525     el.midpoint = el.center = mp;
526 
527     return el;
528 };
529 
530 JXG.registerElement("semicircle", JXG.createSemicircle);
531 
532 /**
533  * @class A circumcircle arc is an {@link Arc} defined by three points. All three points lie on the arc.
534  * @pseudo
535  * @name CircumcircleArc
536  * @augments Arc
537  * @constructor
538  * @type Arc
539  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
540  * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The result will be a composition of an arc of the circumcircle of
541  * <tt>p1</tt>, <tt>p2</tt>, and <tt>p3</tt> and the midpoint of the circumcircle of the three points. The arc is drawn
542  * counter-clockwise from <tt>p1</tt> over <tt>p2</tt> to <tt>p3</tt>.
543  * @example
544  * // Create a circum circle arc out of three free points
545  * var p1 = board.create('point', [2.0, 2.0]);
546  * var p2 = board.create('point', [1.0, 0.5]);
547  * var p3 = board.create('point', [3.5, 1.0]);
548  *
549  * var a = board.create('circumcirclearc', [p1, p2, p3]);
550  * </pre><div class="jxgbox" id="JXG87125fd4-823a-41c1-88ef-d1a1369504e3" style="width: 300px; height: 300px;"></div>
551  * <script type="text/javascript">
552  * (function () {
553  *   var board = JXG.JSXGraph.initBoard('JXG87125fd4-823a-41c1-88ef-d1a1369504e3', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
554  *       p1 = board.create('point', [2.0, 2.0]),
555  *       p2 = board.create('point', [1.0, 0.5]),
556  *       p3 = board.create('point', [3.5, 1.0]),
557  *
558  *       cca = board.create('circumcirclearc', [p1, p2, p3]);
559  * })();
560  * </script><pre>
561  */
562 JXG.createCircumcircleArc = function (board, parents, attributes) {
563     var el, mp, attr, points;
564 
565     // We need three points
566     points = Type.providePoints(board, parents, attributes, "point");
567     if (points === false || points.length !== 3) {
568         throw new Error(
569             "JSXGraph: create Circumcircle Arc with parent types '" +
570                 typeof parents[0] +
571                 "' and '" +
572                 typeof parents[1] +
573                 "' and '" +
574                 typeof parents[2] +
575                 "'." +
576                 "\nPossible parent types: [point,point,point]"
577         );
578     }
579 
580     attr = Type.copyAttributes(attributes, board.options, "circumcirclearc", "center");
581     mp = board.create("circumcenter", points, attr);
582     mp.dump = false;
583 
584     attr = Type.copyAttributes(attributes, board.options, "circumcirclearc");
585     attr.usedirection = true;
586     el = board.create("arc", [mp, points[0], points[2], points[1]], attr);
587 
588     el.elType = "circumcirclearc";
589     el.setParents([points[0].id, points[1].id, points[2].id]);
590     el.subs = {
591         center: mp
592     };
593     el.inherits.push(mp);
594 
595     /**
596      * The midpoint of the circumcircle of the three points defining the circumcircle arc.
597      * @memberOf CircumcircleArc.prototype
598      * @name center
599      * @type Circumcenter
600      */
601     el.center = mp;
602 
603     return el;
604 };
605 
606 JXG.registerElement("circumcirclearc", JXG.createCircumcircleArc);
607 
608 /**
609  * @class A minor arc is a segment of the circumference of a circle having measure less than or equal to
610  * 180 degrees (pi radians). It is defined by a center, one point that
611  * defines the radius, and a third point that defines the angle of the arc.
612  * @pseudo
613  * @name MinorArc
614  * @augments Curve
615  * @constructor
616  * @type JXG.Curve
617  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
618  * @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
619  * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3.
620  * @example
621  * // Create an arc out of three free points
622  * var p1 = board.create('point', [2.0, 2.0]);
623  * var p2 = board.create('point', [1.0, 0.5]);
624  * var p3 = board.create('point', [3.5, 1.0]);
625  *
626  * var a = board.create('arc', [p1, p2, p3]);
627  * </pre><div class="jxgbox" id="JXG64ba7ca2-8728-45f3-96e5-3c7a4414de2f" style="width: 300px; height: 300px;"></div>
628  * <script type="text/javascript">
629  * (function () {
630  *   var board = JXG.JSXGraph.initBoard('JXG64ba7ca2-8728-45f3-96e5-3c7a4414de2f', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
631  *       p1 = board.create('point', [2.0, 2.0]),
632  *       p2 = board.create('point', [1.0, 0.5]),
633  *       p3 = board.create('point', [3.5, 1.0]),
634  *
635  *       a = board.create('minorarc', [p1, p2, p3]);
636  * })();
637  * </script><pre>
638  */
639 
640 JXG.createMinorArc = function (board, parents, attributes) {
641     attributes.selection = "minor";
642     return JXG.createArc(board, parents, attributes);
643 };
644 
645 JXG.registerElement("minorarc", JXG.createMinorArc);
646 
647 /**
648  * @class A major arc is a segment of the circumference of a circle having measure greater than or equal to
649  * 180 degrees (pi radians). It is defined by a center, one point that
650  * defines the radius, and a third point that defines the angle of the arc.
651  * @pseudo
652  * @name MajorArc
653  * @augments Curve
654  * @constructor
655  * @type JXG.Curve
656  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
657  * @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
658  * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3.
659  * @example
660  * // Create an arc out of three free points
661  * var p1 = board.create('point', [2.0, 2.0]);
662  * var p2 = board.create('point', [1.0, 0.5]);
663  * var p3 = board.create('point', [3.5, 1.0]);
664  *
665  * var a = board.create('majorarc', [p1, p2, p3]);
666  * </pre><div class="jxgbox" id="JXG17a10d38-5629-40a4-b150-f41806edee9f" style="width: 300px; height: 300px;"></div>
667  * <script type="text/javascript">
668  * (function () {
669  *   var board = JXG.JSXGraph.initBoard('JXG17a10d38-5629-40a4-b150-f41806edee9f', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
670  *       p1 = board.create('point', [2.0, 2.0]),
671  *       p2 = board.create('point', [1.0, 0.5]),
672  *       p3 = board.create('point', [3.5, 1.0]),
673  *
674  *       a = board.create('majorarc', [p1, p2, p3]);
675  * })();
676  * </script><pre>
677  */
678 JXG.createMajorArc = function (board, parents, attributes) {
679     attributes.selection = "major";
680     return JXG.createArc(board, parents, attributes);
681 };
682 
683 JXG.registerElement("majorarc", JXG.createMajorArc);
684