summaryrefslogtreecommitdiff
path: root/vendor/github.com/golang/geo/s1/angle.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/golang/geo/s1/angle.go')
-rw-r--r--vendor/github.com/golang/geo/s1/angle.go120
1 files changed, 120 insertions, 0 deletions
diff --git a/vendor/github.com/golang/geo/s1/angle.go b/vendor/github.com/golang/geo/s1/angle.go
new file mode 100644
index 000000000..747b23dea
--- /dev/null
+++ b/vendor/github.com/golang/geo/s1/angle.go
@@ -0,0 +1,120 @@
+// Copyright 2014 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package s1
+
+import (
+ "math"
+ "strconv"
+)
+
+// Angle represents a 1D angle. The internal representation is a double precision
+// value in radians, so conversion to and from radians is exact.
+// Conversions between E5, E6, E7, and Degrees are not always
+// exact. For example, Degrees(3.1) is different from E6(3100000) or E7(31000000).
+//
+// The following conversions between degrees and radians are exact:
+//
+// Degree*180 == Radian*math.Pi
+// Degree*(180/n) == Radian*(math.Pi/n) for n == 0..8
+//
+// These identities hold when the arguments are scaled up or down by any power
+// of 2. Some similar identities are also true, for example,
+//
+// Degree*60 == Radian*(math.Pi/3)
+//
+// But be aware that this type of identity does not hold in general. For example,
+//
+// Degree*3 != Radian*(math.Pi/60)
+//
+// Similarly, the conversion to radians means that (Angle(x)*Degree).Degrees()
+// does not always equal x. For example,
+//
+// (Angle(45*n)*Degree).Degrees() == 45*n for n == 0..8
+//
+// but
+//
+// (60*Degree).Degrees() != 60
+//
+// When testing for equality, you should allow for numerical errors (ApproxEqual)
+// or convert to discrete E5/E6/E7 values first.
+type Angle float64
+
+// Angle units.
+const (
+ Radian Angle = 1
+ Degree = (math.Pi / 180) * Radian
+
+ E5 = 1e-5 * Degree
+ E6 = 1e-6 * Degree
+ E7 = 1e-7 * Degree
+)
+
+// Radians returns the angle in radians.
+func (a Angle) Radians() float64 { return float64(a) }
+
+// Degrees returns the angle in degrees.
+func (a Angle) Degrees() float64 { return float64(a / Degree) }
+
+// round returns the value rounded to nearest as an int32.
+// This does not match C++ exactly for the case of x.5.
+func round(val float64) int32 {
+ if val < 0 {
+ return int32(val - 0.5)
+ }
+ return int32(val + 0.5)
+}
+
+// InfAngle returns an angle larger than any finite angle.
+func InfAngle() Angle {
+ return Angle(math.Inf(1))
+}
+
+// isInf reports whether this Angle is infinite.
+func (a Angle) isInf() bool {
+ return math.IsInf(float64(a), 0)
+}
+
+// E5 returns the angle in hundred thousandths of degrees.
+func (a Angle) E5() int32 { return round(a.Degrees() * 1e5) }
+
+// E6 returns the angle in millionths of degrees.
+func (a Angle) E6() int32 { return round(a.Degrees() * 1e6) }
+
+// E7 returns the angle in ten millionths of degrees.
+func (a Angle) E7() int32 { return round(a.Degrees() * 1e7) }
+
+// Abs returns the absolute value of the angle.
+func (a Angle) Abs() Angle { return Angle(math.Abs(float64(a))) }
+
+// Normalized returns an equivalent angle in (-π, π].
+func (a Angle) Normalized() Angle {
+ rad := math.Remainder(float64(a), 2*math.Pi)
+ if rad <= -math.Pi {
+ rad = math.Pi
+ }
+ return Angle(rad)
+}
+
+func (a Angle) String() string {
+ return strconv.FormatFloat(a.Degrees(), 'f', 7, 64) // like "%.7f"
+}
+
+// ApproxEqual reports whether the two angles are the same up to a small tolerance.
+func (a Angle) ApproxEqual(other Angle) bool {
+ return math.Abs(float64(a)-float64(other)) <= epsilon
+}
+
+// BUG(dsymonds): The major differences from the C++ version are:
+// - no unsigned E5/E6/E7 methods