1 /*
  2     Copyright 2008-2026
  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.js";
 41 import Geometry from "../math/geometry.js";
 42 import Mat from "../math/math.js";
 43 import Coords from "../base/coords.js";
 44 import Circle from "../base/circle.js";
 45 import Type from "../utils/type.js";
 46 import Const from "../base/constants.js";
 47 
 48 /**
 49  * @class An arc is a partial circumference line of a circle.
 50  * It is defined by a center, one point that
 51  * defines the radius, and a third point that defines the angle of the arc.
 52  * <p>
 53  * As a curve the arc has curve length 6.
 54  * @pseudo
 55  * @name Arc
 56  * @augments Curve
 57  * @constructor
 58  * @type JXG.Curve
 59  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
 60  * @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
 61  * counter-clockwise from p2 to p3.
 62  * @example
 63  * // Create an arc out of three free points
 64  * var p1 = board.create('point', [2.0, 2.0]);
 65  * var p2 = board.create('point', [1.0, 0.5]);
 66  * var p3 = board.create('point', [3.5, 1.0]);
 67  *
 68  * var a = board.create('arc', [p1, p2, p3]);
 69  * board.create('text',[1,6,function(){return 'arclength: '+Math.round(a.Value()*100)/100}])
 70  * </pre><div class="jxgbox" id="JXG114ef584-4a5e-4686-8392-c97501befb5b" style="width: 300px; height: 300px;"></div>
 71  * <script type="text/javascript">
 72  * (function () {
 73  *   var board = JXG.JSXGraph.initBoard('JXG114ef584-4a5e-4686-8392-c97501befb5b', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
 74  *       p1 = board.create('point', [2.0, 2.0]),
 75  *       p2 = board.create('point', [1.0, 0.5]),
 76  *       p3 = board.create('point', [3.5, 1.0]),
 77  *
 78  *       a = board.create('arc', [p1, p2, p3]);
 79  *       board.create('text',[1,6,function(){return 'arclength: '+Math.round(a.Value()*100)/100}])
 80  * })();
 81  * </script><pre>
 82  *
 83  * @example
 84  * var t = board.create('transform', [2, 1.5], {type: 'scale'});
 85  * var a1 = board.create('arc', [[1, 1], [0, 1], [1, 0]], {strokeColor: 'red'});
 86  * var a2 = board.create('curve', [a1, t], {strokeColor: 'red'});
 87  *
 88  * </pre><div id="JXG1949da46-6339-11e8-9fb9-901b0e1b8723" class="jxgbox" style="width: 300px; height: 300px;"></div>
 89  * <script type="text/javascript">
 90  *     (function() {
 91  *         var board = JXG.JSXGraph.initBoard('JXG1949da46-6339-11e8-9fb9-901b0e1b8723',
 92  *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
 93  *     var t = board.create('transform', [2, 1.5], {type: 'scale'});
 94  *     var a1 = board.create('arc', [[1, 1], [0, 1], [1, 0]], {strokeColor: 'red'});
 95  *     var a2 = board.create('curve', [a1, t], {strokeColor: 'red'});
 96  *
 97  *     })();
 98  *
 99  * </script><pre>
100  *
101  */
102 JXG.createArc = function (board, parents, attributes) {
103     var el, attr, points;
104 
105     // attributes.radiusPoint = {visible: false};
106     points = Type.providePoints(board, parents, attributes, "arc", [
107         "center",
108         "radiuspoint",
109         "anglepoint"
110     ]);
111     if (points === false || points.length < 3) {
112         throw new Error(
113             "JSXGraph: Can't create Arc with parent types '" +
114                 typeof parents[0] +
115                 "' and '" +
116                 typeof parents[1] +
117                 "' and '" +
118                 typeof parents[2] +
119                 "'." +
120                 "\nPossible parent types: [point,point,point], [arc, transformation]"
121         );
122     }
123 
124     attr = Type.copyAttributes(attributes, board.options, 'arc');
125     el = board.create("curve", [[0], [0], 0, 4], attr);
126 
127     el.elType = 'arc';
128     el.setParents(points);
129 
130     /**
131      * documented in JXG.GeometryElement
132      * @ignore
133      */
134     el.type = Const.OBJECT_TYPE_ARC;
135 
136     /**
137      * Center of the arc.
138      * @memberOf Arc.prototype
139      * @name center
140      * @type JXG.Point
141      */
142     el.center = points[0];
143 
144     /**
145      * Point defining the arc's radius.
146      * @memberOf Arc.prototype
147      * @name radiuspoint
148      * @type JXG.Point
149      */
150     el.radiuspoint = points[1];
151     el.point2 = el.radiuspoint;
152 
153     /**
154      * The point defining the arc's angle.
155      * @memberOf Arc.prototype
156      * @name anglepoint
157      * @type JXG.Point
158      */
159     el.anglepoint = points[2];
160     el.point3 = el.anglepoint;
161 
162     // Add arc as child to defining points
163     // or vice versa if the points are provided as coordinates
164     if (Type.exists(el.center._is_new)) {
165         el.addChild(el.center);
166         delete el.center._is_new;
167     } else {
168         el.center.addChild(el);
169     }
170     if (Type.exists(el.radiuspoint._is_new)) {
171         el.addChild(el.radiuspoint);
172         delete el.radiuspoint._is_new;
173     } else {
174         el.radiuspoint.addChild(el);
175     }
176     if (Type.exists(el.anglepoint._is_new)) {
177         el.addChild(el.anglepoint);
178         delete el.anglepoint._is_new;
179     } else {
180         el.anglepoint.addChild(el);
181     }
182 
183     // This attribute is necessary for circumCircleArcs
184     el.useDirection = attr.usedirection; // This makes the attribute immutable
185 
186     // documented in JXG.Curve
187     /**
188      * @class
189      * @ignore
190      */
191     el.updateDataArray = function () {
192         var ar, phi, det,
193             p0c, p1c, p2c,
194             sgn = 1,
195             A = this.radiuspoint,
196             B = this.center,
197             C = this.anglepoint,
198             a, b, c,
199             vp_s = this.evalVisProp('selection'),
200             vp_o = this.evalVisProp('orientation');
201 
202         phi = Geometry.rad(A, B, C);
203         if ((vp_s === 'minor' && phi > Math.PI) || (vp_s === 'major' && phi < Math.PI) || (vp_s === 'auto' && vp_o === 'clockwise')) {
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         if (rad === undefined) {
283             rad = Geometry.rad(this.radiuspoint, this.center, this.anglepoint);
284 
285             if (this.evalVisProp('orientation') === 'clockwise') {
286                 rad = 2 * Math.PI - rad;
287             }
288         }
289 
290         unit = unit || 'length';
291         unit = unit.toLocaleLowerCase();
292         if (unit === '' || unit.indexOf('len') === 0) {
293             val = rad * this.Radius();
294         } else if (unit.indexOf('rad') === 0) {
295             val = rad;
296         } else if (unit.indexOf('deg') === 0) {
297             val = rad * 180 / Math.PI;
298         } else if (unit.indexOf('sem') === 0) {
299             val = rad / Math.PI;
300         } else if (unit.indexOf('cir') === 0) {
301             val = rad * 0.5 / Math.PI;
302         }
303 
304         return val;
305     };
306 
307     /**
308      * Arc length.
309      * @memberOf Arc.prototype
310      * @name L
311      * @returns {Number} Length of the arc.
312      * @see Arc#Value
313      */
314     el.L = function() {
315         return this.Value('length');
316     };
317 
318     // documented in geometry element
319     el.hasPoint = function (x, y) {
320         var dist,
321             checkPoint,
322             has,
323             invMat,
324             c,
325             prec,
326             type,
327             r = this.Radius();
328 
329         if (this.evalVisProp('hasinnerpoints')) {
330             return this.hasPointSector(x, y);
331         }
332 
333         if (Type.isObject(this.evalVisProp('precision'))) {
334             type = this.board._inputDevice;
335             prec = this.evalVisProp('precision.' + type);
336         } else {
337             // 'inherit'
338             prec = this.board.options.precision.hasPoint;
339         }
340         prec /= Math.min(Math.abs(this.board.unitX), Math.abs(this.board.unitY));
341         checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board);
342 
343         if (this.transformations.length > 0) {
344             // Transform the mouse/touch coordinates
345             // back to the original position of the curve.
346             this.updateTransformMatrix();
347             invMat = Mat.inverse(this.transformMat);
348             c = Mat.matVecMult(invMat, checkPoint.usrCoords);
349             checkPoint = new Coords(Const.COORDS_BY_USER, c, this.board);
350         }
351 
352         dist = this.center.coords.distance(Const.COORDS_BY_USER, checkPoint);
353         has = Math.abs(dist - r) < prec;
354 
355         /**
356          * At that point we know that the user has touched the circle line.
357          * Now, we have to check, if the user has hit the arc path.
358          */
359         if (has) {
360             has = Geometry.coordsOnArc(this, checkPoint);
361         }
362         return has;
363     };
364 
365     /**
366      * Checks whether (x,y) is within the sector defined by the arc.
367      * @memberOf Arc.prototype
368      * @name hasPointSector
369      * @function
370      * @param {Number} x Coordinate in x direction, screen coordinates.
371      * @param {Number} y Coordinate in y direction, screen coordinates.
372      * @returns {Boolean} True if (x,y) is within the sector defined by the arc, False otherwise.
373      */
374     el.hasPointSector = function (x, y) {
375         var checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board),
376             r = this.Radius(),
377             dist = this.center.coords.distance(Const.COORDS_BY_USER, checkPoint),
378             has = dist < r;
379 
380         if (has) {
381             has = Geometry.coordsOnArc(this, checkPoint);
382         }
383         return has;
384     };
385 
386     // documented in geometry element
387     el.getTextAnchor = function () {
388         return this.center.coords;
389     };
390 
391     // documented in geometry element
392     /**
393      * @class
394      * @ignore
395      */
396     el.getLabelAnchor = function () {
397         var coords,
398             vec, vecx, vecy,
399             len,
400             pos = this.label.evalVisProp('position'),
401             angle = Geometry.rad(this.radiuspoint, this.center, this.anglepoint),
402             dx = 10 / this.board.unitX,
403             dy = 10 / this.board.unitY,
404             p2c = this.point2.coords.usrCoords,
405             pmc = this.center.coords.usrCoords,
406             bxminusax = p2c[1] - pmc[1],
407             byminusay = p2c[2] - pmc[2],
408             vp_s = this.evalVisProp('selection'),
409             vp_o = this.evalVisProp('orientation'),
410             l_vp = this.label ? this.label.visProp : this.visProp.label;
411 
412         // If this is uncommented, the angle label can not be dragged
413         //if (Type.exists(this.label)) {
414         //    this.label.relativeCoords = new Coords(Const.COORDS_BY_SCREEN, [0, 0], this.board);
415         //}
416 
417         if (
418             !Type.isString(pos) ||
419             (pos.indexOf('right') < 0 && pos.indexOf('left') < 0)
420         ) {
421 
422             if ((vp_s === 'minor' && angle > Math.PI) || (vp_s === 'major' && angle < Math.PI) || (vp_s === 'auto' && vp_o === 'clockwise')) {
423                 angle = -(2 * Math.PI - angle);
424             }
425 
426             coords = new Coords(
427                 Const.COORDS_BY_USER,
428                 [
429                     pmc[1] + Math.cos(angle * 0.5) * bxminusax - Math.sin(angle * 0.5) * byminusay,
430                     pmc[2] + Math.sin(angle * 0.5) * bxminusax + Math.cos(angle * 0.5) * byminusay
431                 ],
432                 this.board
433             );
434 
435             vecx = coords.usrCoords[1] - pmc[1];
436             vecy = coords.usrCoords[2] - pmc[2];
437 
438             len = Mat.hypot(vecx, vecy);
439             vecx = (vecx * (len + dx)) / len;
440             vecy = (vecy * (len + dy)) / len;
441             vec = [pmc[1] + vecx, pmc[2] + vecy];
442 
443             l_vp.position = Geometry.calcLabelQuadrant(Geometry.rad([1, 0], [0, 0], vec));
444 
445             return new Coords(Const.COORDS_BY_USER, vec, this.board);
446         } else {
447             return this.getLabelPosition(pos, this.label.evalVisProp('distance'));
448         }
449 
450     };
451 
452     // documentation in jxg.circle
453     el.updateQuadraticform = Circle.prototype.updateQuadraticform;
454 
455     // documentation in jxg.circle
456     el.updateStdform = Circle.prototype.updateStdform;
457 
458     el.methodMap = JXG.deepCopy(el.methodMap, {
459         getRadius: "getRadius",
460         radius: "Radius",
461         Radius: "Radius",
462         center: "center",
463         radiuspoint: "radiuspoint",
464         anglepoint: "anglepoint",
465         Value: "Value",
466         L: "L"
467     });
468 
469     el.prepareUpdate().update();
470     return el;
471 };
472 
473 JXG.registerElement("arc", JXG.createArc);
474 
475 /**
476  * @class A semicircle is a special arc defined by two points. The arc hits both points.
477  * @pseudo
478  * @name Semicircle
479  * @augments Arc
480  * @constructor
481  * @type Arc
482  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
483  * @param {JXG.Point_JXG.Point} p1,p2 The result will be a composition of an arc drawn clockwise from <tt>p1</tt> and
484  * <tt>p2</tt> and the midpoint of <tt>p1</tt> and <tt>p2</tt>.
485  * @example
486  * // Create an arc out of three free points
487  * var p1 = board.create('point', [4.5, 2.0]);
488  * var p2 = board.create('point', [1.0, 0.5]);
489  *
490  * var a = board.create('semicircle', [p1, p2]);
491  * </pre><div class="jxgbox" id="JXG5385d349-75d7-4078-b732-9ae808db1b0e" style="width: 300px; height: 300px;"></div>
492  * <script type="text/javascript">
493  * (function () {
494  *   var board = JXG.JSXGraph.initBoard('JXG5385d349-75d7-4078-b732-9ae808db1b0e', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
495  *       p1 = board.create('point', [4.5, 2.0]),
496  *       p2 = board.create('point', [1.0, 0.5]),
497  *
498  *       sc = board.create('semicircle', [p1, p2]);
499  * })();
500  * </script><pre>
501  */
502 JXG.createSemicircle = function (board, parents, attributes) {
503     var el, mp, attr, points;
504 
505     // we need 2 points
506     points = Type.providePoints(board, parents, attributes, 'point');
507     if (points === false || points.length !== 2) {
508         throw new Error(
509             "JSXGraph: Can't create Semicircle with parent types '" +
510                 typeof parents[0] +
511                 "' and '" +
512                 typeof parents[1] +
513                 "'." +
514                 "\nPossible parent types: [point,point]"
515         );
516     }
517 
518     attr = Type.copyAttributes(attributes, board.options, "semicircle", 'center');
519     mp = board.create("midpoint", points, attr);
520     mp.dump = false;
521 
522     attr = Type.copyAttributes(attributes, board.options, 'semicircle');
523     el = board.create("arc", [mp, points[1], points[0]], attr);
524     el.elType = 'semicircle';
525     el.setParents([points[0].id, points[1].id]);
526     el.subs = {
527         midpoint: mp
528     };
529     el.inherits.push(mp);
530 
531     /**
532      * The midpoint of the two defining points.
533      * @memberOf Semicircle.prototype
534      * @name midpoint
535      * @type Midpoint
536      */
537     el.midpoint = el.center = mp;
538 
539     return el;
540 };
541 
542 JXG.registerElement("semicircle", JXG.createSemicircle);
543 
544 /**
545  * @class A partial circum circle through three points.
546  * @pseudo
547  * @name CircumcircleArc
548  * @augments Arc
549  * @constructor
550  * @type Arc
551  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
552  * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The result will be a composition of an arc of the circumcircle of
553  * <tt>p1</tt>, <tt>p2</tt>, and <tt>p3</tt> and the midpoint of the circumcircle of the three points. The arc is drawn
554  * counter-clockwise from <tt>p1</tt> over <tt>p2</tt> to <tt>p3</tt>.
555  * @example
556  * // Create a circum circle arc out of three free points
557  * var p1 = board.create('point', [2.0, 2.0]);
558  * var p2 = board.create('point', [1.0, 0.5]);
559  * var p3 = board.create('point', [3.5, 1.0]);
560  *
561  * var a = board.create('circumcirclearc', [p1, p2, p3]);
562  * </pre><div class="jxgbox" id="JXG87125fd4-823a-41c1-88ef-d1a1369504e3" style="width: 300px; height: 300px;"></div>
563  * <script type="text/javascript">
564  * (function () {
565  *   var board = JXG.JSXGraph.initBoard('JXG87125fd4-823a-41c1-88ef-d1a1369504e3', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
566  *       p1 = board.create('point', [2.0, 2.0]),
567  *       p2 = board.create('point', [1.0, 0.5]),
568  *       p3 = board.create('point', [3.5, 1.0]),
569  *
570  *       cca = board.create('circumcirclearc', [p1, p2, p3]);
571  * })();
572  * </script><pre>
573  */
574 JXG.createCircumcircleArc = function (board, parents, attributes) {
575     var el, mp, attr, points;
576 
577     // We need three points
578     points = Type.providePoints(board, parents, attributes, 'point');
579     if (points === false || points.length !== 3) {
580         throw new Error(
581             "JSXGraph: create Circumcircle Arc with parent types '" +
582                 typeof parents[0] +
583                 "' and '" +
584                 typeof parents[1] +
585                 "' and '" +
586                 typeof parents[2] +
587                 "'." +
588                 "\nPossible parent types: [point,point,point]"
589         );
590     }
591 
592     attr = Type.copyAttributes(attributes, board.options, "circumcirclearc", 'center');
593     mp = board.create("circumcenter", points, attr);
594     mp.dump = false;
595 
596     attr = Type.copyAttributes(attributes, board.options, 'circumcirclearc');
597     attr.usedirection = true;
598     el = board.create("arc", [mp, points[0], points[2], points[1]], attr);
599 
600     el.elType = 'circumcirclearc';
601     el.setParents([points[0].id, points[1].id, points[2].id]);
602     el.subs = {
603         center: mp
604     };
605     el.inherits.push(mp);
606 
607     /**
608      * The midpoint of the circumcircle of the three points defining the circumcircle arc.
609      * @memberOf CircumcircleArc.prototype
610      * @name center
611      * @type Circumcenter
612      */
613     el.center = mp;
614 
615     return el;
616 };
617 
618 JXG.registerElement("circumcirclearc", JXG.createCircumcircleArc);
619 
620 /**
621  * @class A minor arc given by three points is that part of the circumference of a circle having
622  * measure at most 180 degrees (pi radians). It is defined by a center, one point that
623  * defines the radius, and a third point that defines the angle of the arc.
624  * @pseudo
625  * @name MinorArc
626  * @augments Curve
627  * @constructor
628  * @type JXG.Curve
629  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
630  * @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
631  * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3.
632  * @example
633  * // Create an arc out of three free points
634  * var p1 = board.create('point', [2.0, 2.0]);
635  * var p2 = board.create('point', [1.0, 0.5]);
636  * var p3 = board.create('point', [3.5, 1.0]);
637  *
638  * var a = board.create('arc', [p1, p2, p3]);
639  * </pre><div class="jxgbox" id="JXG64ba7ca2-8728-45f3-96e5-3c7a4414de2f" style="width: 300px; height: 300px;"></div>
640  * <script type="text/javascript">
641  * (function () {
642  *   var board = JXG.JSXGraph.initBoard('JXG64ba7ca2-8728-45f3-96e5-3c7a4414de2f', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
643  *       p1 = board.create('point', [2.0, 2.0]),
644  *       p2 = board.create('point', [1.0, 0.5]),
645  *       p3 = board.create('point', [3.5, 1.0]),
646  *
647  *       a = board.create('minorarc', [p1, p2, p3]);
648  * })();
649  * </script><pre>
650  */
651 
652 JXG.createMinorArc = function (board, parents, attributes) {
653     attributes.selection = 'minor';
654     return JXG.createArc(board, parents, attributes);
655 };
656 
657 JXG.registerElement("minorarc", JXG.createMinorArc);
658 
659 /**
660  * @class A major arc given by three points is that part of the circumference of a circle having
661  * measure at least 180 degrees (pi radians). It is defined by a center, one point that
662  * defines the radius, and a third point that defines the angle of the arc.
663  * @pseudo
664  * @name MajorArc
665  * @augments Curve
666  * @constructor
667  * @type JXG.Curve
668  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
669  * @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
670  * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3.
671  * @example
672  * // Create an arc out of three free points
673  * var p1 = board.create('point', [2.0, 2.0]);
674  * var p2 = board.create('point', [1.0, 0.5]);
675  * var p3 = board.create('point', [3.5, 1.0]);
676  *
677  * var a = board.create('majorarc', [p1, p2, p3]);
678  * </pre><div class="jxgbox" id="JXG17a10d38-5629-40a4-b150-f41806edee9f" style="width: 300px; height: 300px;"></div>
679  * <script type="text/javascript">
680  * (function () {
681  *   var board = JXG.JSXGraph.initBoard('JXG17a10d38-5629-40a4-b150-f41806edee9f', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),
682  *       p1 = board.create('point', [2.0, 2.0]),
683  *       p2 = board.create('point', [1.0, 0.5]),
684  *       p3 = board.create('point', [3.5, 1.0]),
685  *
686  *       a = board.create('majorarc', [p1, p2, p3]);
687  * })();
688  * </script><pre>
689  */
690 JXG.createMajorArc = function (board, parents, attributes) {
691     attributes.selection = 'major';
692     return JXG.createArc(board, parents, attributes);
693 };
694 
695 JXG.registerElement("majorarc", JXG.createMajorArc);
696