main.js (5287B)
1 /** 2 * @license Apache-2.0 3 * 4 * Copyright (c) 2018 The Stdlib Authors. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * 19 * ## Notice 20 * 21 * The original code, copyright and license are from [Go]{@link https://golang.org/src/math/atan2.go}. The implementation follows the original, but has been modified for JavaScript. 22 * 23 * ```text 24 * Copyright (c) 2009 The Go Authors. All rights reserved. 25 * 26 * Redistribution and use in source and binary forms, with or without 27 * modification, are permitted provided that the following conditions are 28 * met: 29 * 30 * * Redistributions of source code must retain the above copyright 31 * notice, this list of conditions and the following disclaimer. 32 * * Redistributions in binary form must reproduce the above 33 * copyright notice, this list of conditions and the following disclaimer 34 * in the documentation and/or other materials provided with the 35 * distribution. 36 * * Neither the name of Google Inc. nor the names of its 37 * contributors may be used to endorse or promote products derived from 38 * this software without specific prior written permission. 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ``` 52 */ 53 54 'use strict'; 55 56 // MODULES // 57 58 var isinfinite = require( './../../../../base/assert/is-infinite' ); 59 var copysign = require( './../../../../base/special/copysign' ); 60 var signbit = require( '@stdlib/number/float64/base/signbit' ); 61 var isnan = require( './../../../../base/assert/is-nan' ); 62 var atan = require( './../../../../base/special/atan' ); 63 var PINF = require( '@stdlib/constants/float64/pinf' ); 64 var PI = require( '@stdlib/constants/float64/pi' ); 65 66 67 // MAIN // 68 69 /** 70 * Computes the angle in the plane (in radians) between the positive x-axis and the ray from `(0,0)` to the point `(x,y)`. 71 * 72 * ## Special Cases 73 * 74 * ```tex 75 * \begin{align*} 76 * \operatorname{atan2}(y,\mathrm{NaN}) &= \mathrm{NaN}\\ 77 * \operatorname{atan2}(\mathrm{NaN},x) &= \mathrm{NaN}\\ 78 * \operatorname{atan2}( +0,x \ge 0 ) &= +0 \\ 79 * \operatorname{atan2}( -0, x \ge 0 ) &= -0 \\ 80 * \operatorname{atan2}( +0,x \le -0 ) &= +\Pi \\ 81 * \operatorname{atan2}( -0, x \le -0 ) &= -\Pi \\ 82 * \operatorname{atan2}(+\infty, +\infty) &= +\tfrac{\Pi}{4} \\ 83 * \operatorname{atan2}(-\infty, +\infty) &= -\tfrac{\Pi}{4} \\ 84 * \operatorname{atan2}(+\infty, -\infty) &= +\tfrac{3\Pi}{4} \\ 85 * \operatorname{atan2}(-\infty, -\infty) &= -\tfrac{3\Pi}{4} \\ 86 * \operatorname{atan2}(y, +\infty) &= 0.0 \\ 87 * \operatorname{atan2}(y>0, -\infty) &= +\Pi \\ 88 * \operatorname{atan2}(y<0, -\infty) &= -\Pi \\ 89 * \operatorname{atan2}(+\infty, x ) &= +\tfrac{\Pi}{2} \\ 90 * \operatorname{atan2}(-\infty, x ) &= -\tfrac{\Pi}{2} \\ 91 * \end{align*} 92 * ``` 93 * 94 * @param {number} y - `y` coordinate 95 * @param {number} x - `x` coordinate 96 * @returns {number} angle (in radians) 97 * 98 * @example 99 * var v = atan2( 2.0, 2.0 ); // => atan(1.0) 100 * // returns ~0.785 101 * 102 * @example 103 * var v = atan2( 6.0, 2.0 ); // => atan(3.0) 104 * // returns ~1.249 105 * 106 * @example 107 * var v = atan2( -1.0, -1.0 ); // => atan(1.0) - π 108 * // returns ~-2.356 109 * 110 * @example 111 * var v = atan2( 3.0, 0.0 ); // => π/2 112 * // returns ~1.571 113 * 114 * @example 115 * var v = atan2( -2.0, 0.0 ); // => -π/2 116 * // returns ~-1.571 117 * 118 * @example 119 * var v = atan2( 0.0, 0.0 ); 120 * // returns 0.0 121 * 122 * @example 123 * var v = atan2( 3.0, NaN ); 124 * // returns NaN 125 * 126 * @example 127 * var v = atan2( NaN, 2.0 ); 128 * // returns NaN 129 */ 130 function atan2( y, x ) { 131 var q; 132 if ( isnan( x ) || isnan( y ) ) { 133 return NaN; 134 } 135 if ( isinfinite( x ) ) { 136 if ( x === PINF ) { 137 if ( isinfinite( y ) ) { 138 return copysign( PI / 4.0, y ); 139 } 140 return copysign( 0.0, y ); 141 } 142 // Case: x is -Infinity 143 if ( isinfinite( y ) ) { 144 return copysign( 3.0*PI/4.0, y ); 145 } 146 return copysign( PI, y ); 147 } 148 if ( isinfinite( y ) ) { 149 return copysign( PI / 2.0, y ); 150 } 151 if ( y === 0.0 ) { 152 if ( x >= 0.0 && !signbit( x ) ) { 153 return copysign( 0.0, y ); 154 } 155 return copysign( PI, y ); 156 } 157 if ( x === 0.0 ) { 158 return copysign( PI / 2.0, y ); 159 } 160 q = atan( y / x ); 161 if ( x < 0.0 ) { 162 if ( q <= 0.0 ) { 163 return q + PI; 164 } 165 return q - PI; 166 } 167 return q; 168 } 169 170 171 // EXPORTS // 172 173 module.exports = atan2;