-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdelta_test.go
More file actions
133 lines (110 loc) · 3.12 KB
/
delta_test.go
File metadata and controls
133 lines (110 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package nvector_test
import (
"context"
"math"
"testing"
. "github.com/ezzatron/nvector-go"
"github.com/ezzatron/nvector-go/internal/equality"
"github.com/ezzatron/nvector-go/internal/rapidgen"
"github.com/ezzatron/nvector-go/internal/testapi"
"pgregory.net/rapid"
)
func Test_Delta(t *testing.T) {
client, err := testapi.NewClient()
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
client.Close()
})
ctx := context.Background()
t.Run("it matches the reference implementation", func(t *testing.T) {
rapid.Check(t, func(t *rapid.T) {
e := rapidgen.Ellipsoid().Draw(t, "ellipsoid")
from := Position{
Vector: rapidgen.UnitVector().Draw(t, "fromNVector"),
Depth: rapidgen.Depth(e).Draw(t, "fromDepth"),
}
to := Position{
Vector: rapidgen.UnitVector().Draw(t, "toNVector"),
Depth: rapidgen.Depth(e).Draw(t, "toDepth"),
}
f := rapidgen.RotationMatrix().Draw(t, "coordFrame")
want, err := client.Delta(ctx, from, to, e, f)
if err != nil {
t.Fatal(err)
}
got := Delta(from, to, e, f)
if eq, ineq := equality.EqualToVector(got, want, 1e-7); !eq {
equality.ReportInequalities(t, ineq)
}
})
})
}
func Test_Destination(t *testing.T) {
client, err := testapi.NewClient()
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
client.Close()
})
ctx := context.Background()
t.Run("it matches the reference implementation", func(t *testing.T) {
rapid.Check(t, func(t *rapid.T) {
type inputs struct {
From Position
Delta Vector
E Ellipsoid
F Matrix
}
i := rapid.Custom(func(t *rapid.T) inputs {
e := rapidgen.Ellipsoid().Draw(t, "ellipsoid")
return inputs{
From: Position{
Vector: rapidgen.UnitVector().Draw(t, "fromNVector"),
Depth: rapidgen.Depth(e).Draw(t, "fromDepth"),
},
Delta: rapidgen.EcefVector(e).Draw(t, "delta"),
E: e,
F: rapidgen.RotationMatrix().Draw(t, "coordFrame"),
}
}).Filter(func(i inputs) bool {
a := i.E.SemiMajorAxis
f := i.E.Flattening
v := ToECEF(i.From, i.E, i.F).Add(i.Delta).Transform(i.F)
// filter vectors where the x or yz components are zero after rotation
// this causes a division by zero in the Python implementation
if v.X == 0 || v.Y+v.Z == 0 {
return false
}
// filter a case that makes the Python implementation try to find the
// square root of a negative number
// not sure why this happens, the math is beyond me
e2 := 2*f - math.Pow(f, 2)
R2 := math.Pow(v.Y, 2) + math.Pow(v.Z, 2)
p := R2 / math.Pow(a, 2)
q := (1 - e2) / math.Pow(a, 2) * math.Pow(v.X, 2)
r := (p + q - math.Pow(e2, 2)) / 6
s := math.Pow(e2, 2) * p * q / (4 * math.Pow(r, 3))
if math.IsNaN(s) || s <= 0 {
return false
}
return true
}).Draw(t, "inputs")
from := i.From
delta := i.Delta
e := i.E
f := i.F
want, err := client.Destination(ctx, from, delta, e, f)
if err != nil {
t.Fatal(err)
}
got := Destination(from, delta, e, f)
eq, ineq := equality.EqualToVectorWithDepth(got, want, 1e-12, 1e-7)
if !eq {
equality.ReportInequalities(t, ineq)
}
})
})
}