flatten-js
Version:
Javascript library for 2d geometry
627 lines (538 loc) • 45.7 kB
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 && args[0] instanceof Object && 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 && 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 <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 < 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 < 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 <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) && 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) && 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) && 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" <br/>
* Defaults are stroke:"black", strokeWidth:"1", fill:"none"
* @returns {string}
*/
svg(attrs = {}) {
let largeArcFlag = this.sweep <= 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 && id.length > 0) ? `id="${id}"` : "";
let class_str = (className && 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<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>