Skip to content

Commit 740aa86

Browse files
committed
s1: Update ChordAngle comments
1 parent a63082e commit 740aa86

File tree

1 file changed

+79
-9
lines changed

1 file changed

+79
-9
lines changed

s1/chordangle.go

+79-9
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,84 @@ import (
2626
// to be calculated and compared. Otherwise it is simpler to use Angle.
2727
//
2828
// ChordAngle loses some accuracy as the angle approaches π radians.
29-
// Specifically, the representation of (π - x) radians has an error of about
30-
// (1e-15 / x), with a maximum error of about 2e-8 radians (about 13cm on the
31-
// Earth's surface). For comparison, for angles up to π/2 radians (10000km)
32-
// the worst-case representation error is about 2e-16 radians (1 nanonmeter),
33-
// which is about the same as Angle.
34-
//
35-
// ChordAngles are represented by the squared chord length, which can
36-
// range from 0 to 4. Positive infinity represents an infinite squared length.
29+
// There are several different ways to measure this error, including the
30+
// representational error (i.e., how accurately ChordAngle can represent
31+
// angles near π radians), the conversion error (i.e., how much precision is
32+
// lost when an Angle is converted to an ChordAngle), and the measurement
33+
// error (i.e., how accurate the ChordAngle(a, b) constructor is when the
34+
// points A and B are separated by angles close to π radians). All of these
35+
// errors differ by a small constant factor.
36+
//
37+
// For the measurement error (which is the largest of these errors and also
38+
// the most important in practice), let the angle between A and B be (π - x)
39+
// radians, i.e. A and B are within "x" radians of being antipodal. The
40+
// corresponding chord length is
41+
//
42+
// r = 2 * sin((π - x) / 2) = 2 * cos(x / 2)
43+
//
44+
// For values of x not close to π the relative error in the squared chord
45+
// length is at most 4.5 * dblEpsilon (see MaxPointError below).
46+
// The relative error in "r" is thus at most 2.25 * dblEpsilon ~= 5e-16. To
47+
// convert this error into an equivalent angle, we have
48+
//
49+
// |dr / dx| = sin(x / 2)
50+
//
51+
// and therefore
52+
//
53+
// |dx| = dr / sin(x / 2)
54+
// = 5e-16 * (2 * cos(x / 2)) / sin(x / 2)
55+
// = 1e-15 / tan(x / 2)
56+
//
57+
// The maximum error is attained when
58+
//
59+
// x = |dx|
60+
// = 1e-15 / tan(x / 2)
61+
// ~= 1e-15 / (x / 2)
62+
// ~= sqrt(2e-15)
63+
//
64+
// In summary, the measurement error for an angle (π - x) is at most
65+
//
66+
// dx = min(1e-15 / tan(x / 2), sqrt(2e-15))
67+
// (~= min(2e-15 / x, sqrt(2e-15)) when x is small)
68+
//
69+
// On the Earth's surface (assuming a radius of 6371km), this corresponds to
70+
// the following worst-case measurement errors:
71+
//
72+
// Accuracy: Unless antipodal to within:
73+
// --------- ---------------------------
74+
// 6.4 nanometers 10,000 km (90 degrees)
75+
// 1 micrometer 81.2 kilometers
76+
// 1 millimeter 81.2 meters
77+
// 1 centimeter 8.12 meters
78+
// 28.5 centimeters 28.5 centimeters
79+
//
80+
// The representational and conversion errors referred to earlier are somewhat
81+
// smaller than this. For example, maximum distance between adjacent
82+
// representable ChordAngle values is only 13.5 cm rather than 28.5 cm. To
83+
// see this, observe that the closest representable value to r^2 = 4 is
84+
// r^2 = 4 * (1 - dblEpsilon / 2). Thus r = 2 * (1 - dblEpsilon / 4) and
85+
// the angle between these two representable values is
86+
//
87+
// x = 2 * acos(r / 2)
88+
// = 2 * acos(1 - dblEpsilon / 4)
89+
// ~= 2 * asin(sqrt(dblEpsilon / 2)
90+
// ~= sqrt(2 * dblEpsilon)
91+
// ~= 2.1e-8
92+
//
93+
// which is 13.5 cm on the Earth's surface.
94+
//
95+
// The worst case rounding error occurs when the value halfway between these
96+
// two representable values is rounded up to 4. This halfway value is
97+
// r^2 = (4 * (1 - dblEpsilon / 4)), thus r = 2 * (1 - dblEpsilon / 8) and
98+
// the worst case rounding error is
99+
//
100+
// x = 2 * acos(r / 2)
101+
// = 2 * acos(1 - dblEpsilon / 8)
102+
// ~= 2 * asin(sqrt(dblEpsilon / 4)
103+
// ~= sqrt(dblEpsilon)
104+
// ~= 1.5e-8
105+
//
106+
// which is 9.5 cm on the Earth's surface.
37107
type ChordAngle float64
38108

39109
const (
@@ -225,7 +295,7 @@ func (c ChordAngle) Sin() float64 {
225295
// It is more efficient than Sin.
226296
func (c ChordAngle) Sin2() float64 {
227297
// Let a be the (non-squared) chord length, and let A be the corresponding
228-
// half-angle (a = 2*sin(A)). The formula below can be derived from:
298+
// half-angle (a = 2*sin(A)). The formula below can be derived from:
229299
// sin(2*A) = 2 * sin(A) * cos(A)
230300
// cos^2(A) = 1 - sin^2(A)
231301
// This is much faster than converting to an angle and computing its sine.

0 commit comments

Comments
 (0)