blob: d84b332c9924cf4c0425b94cec8b6e1ac1618e76 [file] [log] [blame]
Ken Thompson21810982008-03-28 13:56:47 -07001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Rob Pike43312932008-06-27 17:06:23 -07005package math
Ken Thompson21810982008-03-28 13:56:47 -07006
Russ Coxb4586a72009-11-17 08:39:56 -08007// Atan2 returns the arc tangent of y/x, using
Russ Coxdfc39102009-03-05 13:31:01 -08008// the signs of the two to determine the quadrant
9// of the return value.
Charles L. Dorian072b5602010-02-05 14:55:19 -080010//
11// Special cases are (in order):
12// Atan2(y, NaN) = NaN
13// Atan2(NaN, x) = NaN
Charles L. Dorian9aa8f952010-04-08 13:24:04 -070014// Atan2(+0, x>=0) = +0
15// Atan2(-0, x>=0) = -0
16// Atan2(+0, x<=-0) = +Pi
17// Atan2(-0, x<=-0) = -Pi
Charles L. Dorian072b5602010-02-05 14:55:19 -080018// Atan2(y>0, 0) = +Pi/2
19// Atan2(y<0, 0) = -Pi/2
20// Atan2(+Inf, +Inf) = +Pi/4
21// Atan2(-Inf, +Inf) = -Pi/4
22// Atan2(+Inf, -Inf) = 3Pi/4
23// Atan2(-Inf, -Inf) = -3Pi/4
24// Atan2(y, +Inf) = 0
25// Atan2(y>0, -Inf) = +Pi
26// Atan2(y<0, -Inf) = -Pi
27// Atan2(+Inf, x) = +Pi/2
28// Atan2(-Inf, x) = -Pi/2
Russ Coxdd8dc6f2011-12-13 15:20:12 -050029func Atan2(y, x float64) float64
30
31func atan2(y, x float64) float64 {
Charles L. Dorian072b5602010-02-05 14:55:19 -080032 // special cases
33 switch {
Luuk van Dijk8dd3de42012-02-01 16:08:31 +010034 case IsNaN(y) || IsNaN(x):
Charles L. Dorian072b5602010-02-05 14:55:19 -080035 return NaN()
36 case y == 0:
Charles L. Dorian9aa8f952010-04-08 13:24:04 -070037 if x >= 0 && !Signbit(x) {
38 return Copysign(0, y)
Charles L. Dorian072b5602010-02-05 14:55:19 -080039 }
Charles L. Dorian9aa8f952010-04-08 13:24:04 -070040 return Copysign(Pi, y)
Charles L. Dorian072b5602010-02-05 14:55:19 -080041 case x == 0:
Charles L. Dorian9aa8f952010-04-08 13:24:04 -070042 return Copysign(Pi/2, y)
Luuk van Dijk8dd3de42012-02-01 16:08:31 +010043 case IsInf(x, 0):
44 if IsInf(x, 1) {
Charles L. Dorian072b5602010-02-05 14:55:19 -080045 switch {
Luuk van Dijk8dd3de42012-02-01 16:08:31 +010046 case IsInf(y, 0):
Charles L. Dorian9aa8f952010-04-08 13:24:04 -070047 return Copysign(Pi/4, y)
Charles L. Dorian072b5602010-02-05 14:55:19 -080048 default:
Charles L. Dorian9aa8f952010-04-08 13:24:04 -070049 return Copysign(0, y)
Charles L. Dorian072b5602010-02-05 14:55:19 -080050 }
51 }
52 switch {
Luuk van Dijk8dd3de42012-02-01 16:08:31 +010053 case IsInf(y, 0):
Charles L. Dorian9aa8f952010-04-08 13:24:04 -070054 return Copysign(3*Pi/4, y)
Charles L. Dorian072b5602010-02-05 14:55:19 -080055 default:
Charles L. Dorian9aa8f952010-04-08 13:24:04 -070056 return Copysign(Pi, y)
Charles L. Dorian072b5602010-02-05 14:55:19 -080057 }
Luuk van Dijk8dd3de42012-02-01 16:08:31 +010058 case IsInf(y, 0):
Charles L. Dorian9aa8f952010-04-08 13:24:04 -070059 return Copysign(Pi/2, y)
Ken Thompson21810982008-03-28 13:56:47 -070060 }
Charles L. Dorian072b5602010-02-05 14:55:19 -080061
62 // Call atan and determine the quadrant.
Robert Griesemera3d10452009-12-15 15:35:38 -080063 q := Atan(y / x)
Russ Coxb4586a72009-11-17 08:39:56 -080064 if x < 0 {
Russ Coxdfc39102009-03-05 13:31:01 -080065 if q <= 0 {
Robert Griesemer3bb00322009-11-09 21:23:52 -080066 return q + Pi
Ken Thompson21810982008-03-28 13:56:47 -070067 }
Robert Griesemera3d10452009-12-15 15:35:38 -080068 return q - Pi
Ken Thompson21810982008-03-28 13:56:47 -070069 }
Robert Griesemera3d10452009-12-15 15:35:38 -080070 return q
Ken Thompson21810982008-03-28 13:56:47 -070071}