      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