UNPKG

flatten-js

Version:

Javascript library for 2d geometry

627 lines (538 loc) 45.7 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>classes/arc.js - Documentation</title> <script src="scripts/prettify/prettify.js"></script> <script src="scripts/prettify/lang-css.js"></script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css"> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger" class="navicon-button x"> <div class="navicon"></div> </label> <label for="nav-trigger" class="overlay"></label> <nav> <li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.Arc.html">Arc</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#breakToFunctional">breakToFunctional</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#chordHeight">chordHeight</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#contains">contains</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#distanceTo">distanceTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#intersect">intersect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#middle">middle</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#reverse">reverse</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#rotate">rotate</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#split">split</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#svg">svg</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#tangentInEnd">tangentInEnd</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#tangentInStart">tangentInStart</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#toJSON">toJSON</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#transform">transform</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Arc.html#translate">translate</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.Box.html">Box</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Box.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Box.html#equal_to">equal_to</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Box.html#intersect">intersect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Box.html#less_than">less_than</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Box.html#merge">merge</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Box.html#not_intersect">not_intersect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Box.html#set">set</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Box.html#svg">svg</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.Circle.html">Circle</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Circle.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Circle.html#contains">contains</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Circle.html#distanceTo">distanceTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Circle.html#intersect">intersect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Circle.html#svg">svg</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Circle.html#toArc">toArc</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Circle.html#toJSON">toJSON</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.Edge.html">Edge</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Edge.html#contains">contains</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Edge.html#middle">middle</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Edge.html#setInclusion">setInclusion</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Edge.html#setOverlap">setOverlap</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.Face.html">Face</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Face.html#append">append</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Face.html#area">area</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Face.html#insert">insert</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Face.html#isEmpty">isEmpty</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Face.html#isSimple">isSimple</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Face.html#orientation">orientation</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Face.html#remove">remove</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Face.html#reverse">reverse</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Face.html#setArcLength">setArcLength</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Face.html#signedArea">signedArea</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Face.html#svg">svg</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.Image.html">Image</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.Line.html">Line</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Line.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Line.html#contains">contains</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Line.html#distanceTo">distanceTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Line.html#incidentTo">incidentTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Line.html#intersect">intersect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Line.html#parallelTo">parallelTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Line.html#svg">svg</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Line.html#toJSON">toJSON</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.Matrix.html">Matrix</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Matrix.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Matrix.html#equalTo">equalTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Matrix.html#multiply">multiply</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Matrix.html#rotate">rotate</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Matrix.html#scale">scale</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Matrix.html#transform">transform</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Matrix.html#translate">translate</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.PlanarSet.html">PlanarSet</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.PlanarSet.html#add">add</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.PlanarSet.html#clear">clear</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.PlanarSet.html#delete">delete</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.PlanarSet.html#hit">hit</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.PlanarSet.html#search">search</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.PlanarSet.html#svg">svg</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.Point.html">Point</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Point.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Point.html#distanceTo">distanceTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Point.html#equalTo">equalTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Point.html#leftTo">leftTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Point.html#lessThan">lessThan</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Point.html#on">on</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Point.html#projectionOn">projectionOn</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Point.html#rotate">rotate</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Point.html#svg">svg</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Point.html#toJSON">toJSON</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Point.html#transform">transform</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Point.html#translate">translate</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.Polygon.html">Polygon</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#addFace">addFace</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#addVertex">addVertex</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#area">area</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#contains">contains</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#deleteFace">deleteFace</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#distanceTo">distanceTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#intersect">intersect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#isEmpty">isEmpty</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#isValid">isValid</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#removeChain">removeChain</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#rotate">rotate</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#svg">svg</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#toJSON">toJSON</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#transform">transform</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Polygon.html#translate">translate</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.Ray.html">Ray</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Ray.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Ray.html#intersect">intersect</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.Segment.html">Segment</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#contains">contains</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#distanceTo">distanceTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#equalTo">equalTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#intersect">intersect</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#isZeroLength">isZeroLength</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#middle">middle</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#reverse">reverse</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#rotate">rotate</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#split">split</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#svg">svg</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#tangentInEnd">tangentInEnd</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#tangentInStart">tangentInStart</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#toJSON">toJSON</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#transform">transform</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Segment.html#translate">translate</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Flatten.Vector.html">Vector</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#add">add</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#angleTo">angleTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#clone">clone</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#cross">cross</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#dot">dot</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#equalTo">equalTo</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#invert">invert</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#multiply">multiply</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#normalize">normalize</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#projectionOn">projectionOn</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#rotate">rotate</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#rotate90CCW">rotate90CCW</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#rotate90CW">rotate90CW</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#subtract">subtract</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Flatten.Vector.html#toJSON">toJSON</a></span></li><li class="nav-heading"><a href="global.html">Globals</a></li><li class="nav-item"><span class="nav-item-type type-member">M</span><span class="nav-item-name"><a href="global.html#DP_TOL">DP_TOL</a></span></li> </nav> <div id="main"> <h1 class="page-title">classes/arc.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/** * Created by Alex Bol on 3/10/2017. */ "use strict"; module.exports = function(Flatten) { /** * Class representing a circular arc * @type {Arc} */ Flatten.Arc = class Arc { /** * * @param {Point} pc - arc center * @param {number} r - arc radius * @param {number} startAngle - start angle in radians from 0 to 2*PI * @param {number} endAngle - end angle in radians from 0 to 2*PI * @param {boolean} counterClockwise - arc direction, true - clockwise, false - counter clockwise */ constructor(...args) { /** * Arc center * @type {Point} */ this.pc = new Flatten.Point(); /** * Arc radius * @type {number} */ this.r = 1; /** * Arc start angle in radians * @type {number} */ this.startAngle = 0; /** * Arc end angle in radians * @type {number} */ this.endAngle = 2*Math.PI; /** * Arc orientation * @type {boolean} */ this.counterClockwise = Flatten.CCW; if (args.length == 0) return; if (args.length == 1 &amp;&amp; args[0] instanceof Object &amp;&amp; args[0].name === "arc") { let {pc, r, startAngle, endAngle, counterClockwise} = args[0]; this.pc = new Flatten.Point(pc.x, pc.y); this.r = r; this.startAngle = startAngle; this.endAngle = endAngle; this.counterClockwise = counterClockwise; return; } else { let [pc, r, startAngle, endAngle, counterClockwise] = [...args]; if (pc &amp;&amp; pc instanceof Flatten.Point) this.pc = pc.clone(); if (r !== undefined) this.r = r; if (startAngle !== undefined) this.startAngle = startAngle; if (endAngle!== undefined) this.endAngle = endAngle; if (counterClockwise !== undefined) this.counterClockwise = counterClockwise; return; } throw Flatten.Errors.ILLEGAL_PARAMETERS; } /** * Return new instance of arc * @returns {Arc} */ clone() { return new Flatten.Arc(this.pc.clone(), this.r, this.startAngle, this.endAngle, this.counterClockwise); } /** * Get sweep angle in radians. Sweep angle is non-negative number from 0 to 2*PI * @returns {number} */ get sweep() { if (Flatten.Utils.EQ(this.startAngle, this.endAngle)) return 0.0; if (Flatten.Utils.EQ(Math.abs(this.startAngle - this.endAngle), Flatten.PIx2)) { return Flatten.PIx2; } let sweep; if (this.counterClockwise) { sweep = Flatten.Utils.GT(this.endAngle, this.startAngle) ? this.endAngle - this.startAngle : this.endAngle - this.startAngle + Flatten.PIx2; } else { sweep = Flatten.Utils.GT(this.startAngle, this.endAngle) ? this.startAngle - this.endAngle : this.startAngle - this.endAngle + Flatten.PIx2; } if ( Flatten.Utils.GT(sweep, Flatten.PIx2) ) { sweep -= Flatten.PIx2; } if ( Flatten.Utils.LT(sweep, 0) ) { sweep += Flatten.PIx2; } return sweep; } /** * Get start point of arc * @returns {Point} */ get start() { let p0 = new Flatten.Point(this.pc.x + this.r, this.pc.y); return p0.rotate(this.startAngle, this.pc); } /** * Get end point of arc * @returns {Point} */ get end() { let p0 = new Flatten.Point(this.pc.x + this.r, this.pc.y); return p0.rotate(this.endAngle, this.pc); } /** * Get center of arc * @returns {Point} */ get center() { return this.pc.clone(); } get vertices() { return [this.start.clone(), this.end.clone()]; } /** * Get arc length * @returns {number} */ get length() { return Math.abs(this.sweep*this.r); } /** * Get bounding box of the arc * @returns {Box} */ get box() { let func_arcs = this.breakToFunctional(); let box = func_arcs.reduce( (acc, arc) => acc.merge(arc.start.box), new Flatten.Box() ); box = box.merge(this.end.box); return box; } /** * Returns true if arc contains point, false otherwise * @param {Point} pt - point to test * @returns {boolean} */ contains(pt) { // first check if point on circle (pc,r) if (!Flatten.Utils.EQ(this.pc.distanceTo(pt)[0], this.r)) return false; // point on circle if (pt.equalTo(this.start)) return true; let angle = new Flatten.Vector(this.pc, pt).slope; let test_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, angle, this.counterClockwise); return Flatten.Utils.LE(test_arc.length, this.length); } /** * When given point belongs to arc, return array of two arcs split by this point. If points is incident * to start or end point of the arc, return clone of the arc. If point does not belong to the arcs, return * empty array. * @param {Point} pt Query point * @returns {Arc[]} */ split(pt) { if (!this.contains(pt)) return []; if (Flatten.Utils.EQ_0(this.sweep)) return [this.clone()]; if (this.start.equalTo(pt) || this.end.equalTo(pt)) return [this.clone()]; let angle = new Flatten.Vector(this.pc, pt).slope; return [ new Flatten.Arc(this.pc, this.r, this.startAngle, angle, this.counterClockwise), new Flatten.Arc(this.pc, this.r, angle, this.endAngle, this.counterClockwise) ] } /** * Return middle point of the arc * @returns {Point} */ middle() { let endAngle = this.counterClockwise ? this.startAngle + this.sweep/2 : this.startAngle - this.sweep/2; let arc = new Flatten.Arc(this.pc, this.r, this.startAngle, endAngle, this.counterClockwise); return arc.end; } /** * Returns chord height ("sagitta") of the arc * @returns {number} */ chordHeight() { return (1.0 - Math.cos(Math.abs(this.sweep/2.0))) * this.r; } /** * Returns array of intersection points between arc and other shape * @param {Shape} shape Shape of the one of supported types &lt;br/> * @returns {Points[]} */ intersect(shape) { if (shape instanceof Flatten.Point) { return this.contains(shape) ? [shape] : []; } if (shape instanceof Flatten.Line) { return shape.intersect(this); } if (shape instanceof Flatten.Circle) { return Arc.intersectArc2Circle(this, shape); } if (shape instanceof Flatten.Segment) { return shape.intersect(this); } if (shape instanceof Flatten.Arc) { return Arc.intersectArc2Arc(this, shape); } if (shape instanceof Flatten.Polygon) { return Flatten.Polygon.intersectShape2Polygon(this, shape); } } /** * Calculate distance and shortest segment from arc to shape and return array [distance, shortest segment] * @param {Shape} shape Shape of the one of supported types Point, Line, Circle, Segment, Arc, Polygon or Planar Set * @returns {number} distance from arc to shape * @returns {Segment} shortest segment between arc and shape (started at arc, ended at shape) */ distanceTo(shape) { let {Distance} = Flatten; if (shape instanceof Flatten.Point) { let [dist, shortest_segment] = Distance.point2arc(shape, this); shortest_segment = shortest_segment.reverse(); return [dist, shortest_segment]; } if (shape instanceof Flatten.Circle) { let [dist, shortest_segment] = Distance.arc2circle(this, shape); return [dist, shortest_segment]; } if (shape instanceof Flatten.Line) { let [dist, shortest_segment] = Distance.arc2line(this, shape); return [dist, shortest_segment]; } if (shape instanceof Flatten.Segment) { let [dist, shortest_segment] = Distance.segment2arc(shape, this); shortest_segment = shortest_segment.reverse(); return [dist, shortest_segment]; } if (shape instanceof Flatten.Arc) { let [dist, shortest_segment] = Distance.arc2arc(this, shape); return [dist, shortest_segment]; } if (shape instanceof Flatten.Polygon) { let [dist, shortest_segment] = Distance.shape2polygon(this, shape); return [dist, shortest_segment]; } if (shape instanceof Flatten.PlanarSet) { let [dist, shortest_segment] = Distance.shape2planarSet(this, shape); return [dist, shortest_segment]; } } /** * Breaks arc in extreme point 0, pi/2, pi, 3*pi/2 and returns array of sub-arcs * @returns {Arcs[]} */ breakToFunctional() { let func_arcs_array = []; let angles = [0, Math.PI/2, 2*Math.PI/2, 3*Math.PI/2]; let pts = [ this.pc.translate(this.r,0), this.pc.translate(0,this.r), this.pc.translate(-this.r,0), this.pc.translate(0,-this.r) ]; // If arc contains extreme point, // create test arc started at start point and ended at this extreme point let test_arcs = []; for (let i=0; i &lt; 4; i++) { if (pts[i].on(this)) { test_arcs.push(new Flatten.Arc(this.pc, this.r, this.startAngle, angles[i], this.counterClockwise)); } } if (test_arcs.length == 0) { // arc does contain any extreme point func_arcs_array.push(this.clone()); } else { // arc passes extreme point // sort these arcs by length test_arcs.sort((arc1, arc2) => arc1.length - arc2.length); for (let i = 0; i &lt; test_arcs.length; i++) { let prev_arc = func_arcs_array.length > 0 ? func_arcs_array[func_arcs_array.length - 1] : undefined; let new_arc; if (prev_arc) { new_arc = new Flatten.Arc(this.pc, this.r, prev_arc.endAngle, test_arcs[i].endAngle, this.counterClockwise); } else { new_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, test_arcs[i].endAngle, this.counterClockwise); } if (!Flatten.Utils.EQ_0(new_arc.length)) { func_arcs_array.push(new_arc.clone()); } } // add last sub arc let prev_arc = func_arcs_array.length > 0 ? func_arcs_array[func_arcs_array.length - 1] : undefined; let new_arc; if (prev_arc) { new_arc = new Flatten.Arc(this.pc, this.r, prev_arc.endAngle, this.endAngle, this.counterClockwise); } else { new_arc = new Flatten.Arc(this.pc, this.r, this.startAngle, this.endAngle, this.counterClockwise); } if (!Flatten.Utils.EQ_0(new_arc.length)) { func_arcs_array.push(new_arc.clone()); } } return func_arcs_array; } /** * Return tangent unit vector in the start point in the direction from start to end * @returns {Vector} */ tangentInStart() { let vec = new Flatten.Vector(this.pc, this.start); let angle = this.counterClockwise ? Math.PI/2. : -Math.PI/2.; let tangent = vec.rotate(angle).normalize(); return tangent; } /** * Return tangent unit vector in the end point in the direction from end to start * @returns {Vector} */ tangentInEnd() { let vec = new Flatten.Vector(this.pc, this.end); let angle = this.counterClockwise ? -Math.PI/2. : Math.PI/2.; let tangent = vec.rotate(angle).normalize(); return tangent; } /** * Returns new arc with swapped start and end angles and reversed direction * @returns {Arc} */ reverse() { return new Arc(this.pc, this.r, this.endAngle, this.startAngle, !this.counterClockwise); } /** * Returns new arc translated by vector vec * @param {Vector} vec * @returns {Segment} */ translate(...args) { let arc = this.clone(); arc.pc = this.pc.translate(...args); return arc; } /** * Return new segment rotated by given angle around given point * If point omitted, rotate around origin (0,0) * Positive value of angle defines rotation counter clockwise, negative - clockwise * @param {number} angle - rotation angle in radians * @param {Point} center - center point, default is (0,0) * @returns {Arc} */ rotate(angle = 0, center = new Flatten.Point()) { let m = new Flatten.Matrix(); m = m.translate(center.x, center.y).rotate(angle).translate(-center.x, -center.y); return this.transform(m); } /** * Return new arc transformed using affine transformation matrix &lt;br/> * Note, that non-equal scaling by x and y (matrix[0] != matrix[3]) produce illegal result * TODO: support non-equal scaling arc to ellipse or throw exception ? * @param {Matrix} matrix - affine transformation matrix * @returns {Arc} */ transform(matrix = new Flatten.Matrix()) { let newStart = this.start.transform(matrix); let newEnd = this.end.transform(matrix); let newCenter = this.pc.transform(matrix); let arc = Arc.arcSE(newCenter, newStart, newEnd, this.counterClockwise); return arc; } static arcSE(center, start, end, counterClockwise) { let {vector} = Flatten; let startAngle = vector(center,start).slope; let endAngle = vector(center, end).slope; if (Flatten.Utils.EQ(startAngle, endAngle)) { endAngle += 2*Math.PI; counterClockwise = true; } let r = vector(center, start).length; return new Arc(center, r, startAngle, endAngle, counterClockwise); } static intersectArc2Arc(arc1, arc2) { var ip = []; if (arc1.box.not_intersect(arc2.box)) { return ip; } // Special case: overlapping arcs // May return up to 4 intersection points if (arc1.pc.equalTo(arc2.pc) &amp;&amp; Flatten.Utils.EQ(arc1.r, arc2.r)) { let pt; pt = arc1.start; if (pt.on(arc2)) ip.push(pt); pt = arc1.end; if (pt.on(arc2)) ip.push(pt); pt = arc2.start; if (pt.on(arc1)) ip.push(pt); pt = arc2.end; if (pt.on(arc1)) ip.push(pt); return ip; } // Common case let circle1 = new Flatten.Circle(arc1.pc, arc1.r); let circle2 = new Flatten.Circle(arc2.pc, arc2.r); let ip_tmp = circle1.intersect(circle2); for (let pt of ip_tmp) { if (pt.on(arc1) &amp;&amp; pt.on(arc2)) { ip.push(pt); } } return ip; } static intersectArc2Circle(arc, circle) { let ip = []; if (arc.box.not_intersect(circle.box)) { return ip; } // Case when arc center incident to circle center // Return arc's end points as 2 intersection points if (circle.pc.equalTo(arc.pc) &amp;&amp; Flatten.Utils.EQ(circle.r, arc.r)) { ip.push(arc.start); ip.push(arc.end); return ip; } // Common case let circle1 = circle; let circle2 = new Flatten.Circle(arc.pc, arc.r); let ip_tmp = circle1.intersect(circle2); for (let pt of ip_tmp) { if (pt.on(arc)) { ip.push(pt); } } return ip; } definiteIntegral(ymin=0) { let f_arcs = this.breakToFunctional(); let area = f_arcs.reduce( (acc, arc) => acc + arc.circularSegmentDefiniteIntegral(ymin), 0.0 ); return area; } circularSegmentDefiniteIntegral(ymin) { let line = new Flatten.Line(this.start, this.end); let onLeftSide = this.pc.leftTo(line); let segment = new Flatten.Segment(this.start, this.end); let areaTrapez = segment.definiteIntegral(ymin); let areaCircularSegment = this.circularSegmentArea(); let area = onLeftSide ? areaTrapez - areaCircularSegment : areaTrapez + areaCircularSegment; return area; } circularSegmentArea() { return (0.5*this.r*this.r*(this.sweep - Math.sin(this.sweep))) } /** * Return string to draw arc in svg * @param {Object} attrs - an object with attributes of svg path element, * like "stroke", "strokeWidth", "fill" &lt;br/> * Defaults are stroke:"black", strokeWidth:"1", fill:"none" * @returns {string} */ svg(attrs = {}) { let largeArcFlag = this.sweep &lt;= Math.PI ? "0" : "1"; let sweepFlag = this.counterClockwise ? "1" : "0"; let {stroke, strokeWidth, fill, id, className} = attrs; // let rest_str = Object.keys(rest).reduce( (acc, key) => acc += ` ${key}="${rest[key]}"`, ""); let id_str = (id &amp;&amp; id.length > 0) ? `id="${id}"` : ""; let class_str = (className &amp;&amp; className.length > 0) ? `class="${className}"` : ""; if (Flatten.Utils.EQ(this.sweep, 2*Math.PI)) { let circle = new Flatten.Circle(this.pc, this.r); return circle.svg(attrs); } else { return `\n&lt;path d="M${this.start.x},${this.start.y} A${this.r},${this.r} 0 ${largeArcFlag},${sweepFlag} ${this.end.x},${this.end.y}" stroke="${stroke || "black"}" stroke-width="${strokeWidth || 1}" fill="${fill || "none"}" ${id_str} ${class_str} />` } } /** * This method returns an object that defines how data will be * serialized when called JSON.stringify() method * @returns {Object} */ toJSON() { return Object.assign({},this,{name:"arc"}); } }; /** * Function to create arc equivalent to "new" constructor * @param args */ Flatten.arc = (...args) => new Flatten.Arc(...args); };</code></pre> </article> </section> </div> <br class="clear"> <footer> Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Fri Dec 07 2018 09:41:42 GMT+0200 (Jerusalem Standard Time) using the Minami theme. </footer> <script>prettyPrint();</script> <script src="scripts/linenumber.js"></script> </body> </html>