spatial/r3: implement Rotate

Updates gonum/gonum#1513.
This commit is contained in:
Sebastien Binet
2020-12-01 10:52:18 +01:00
committed by GitHub
parent 8d1ffe1e87
commit 9c06200335
2 changed files with 92 additions and 1 deletions

View File

@@ -236,6 +236,32 @@ func TestCos(t *testing.T) {
}
}
func TestRotate(t *testing.T) {
const tol = 1e-14
for _, test := range []struct {
v, axis Vec
alpha float64
want Vec
}{
{Vec{1, 0, 0}, Vec{1, 0, 0}, math.Pi / 2, Vec{1, 0, 0}},
{Vec{1, 0, 0}, Vec{1, 0, 0}, 0, Vec{1, 0, 0}},
{Vec{1, 0, 0}, Vec{1, 0, 0}, 2 * math.Pi, Vec{1, 0, 0}},
{Vec{1, 0, 0}, Vec{0, 0, 0}, math.Pi / 2, Vec{math.NaN(), math.NaN(), math.NaN()}},
{Vec{1, 0, 0}, Vec{0, 1, 0}, math.Pi / 2, Vec{0, 0, -1}},
{Vec{1, 0, 0}, Vec{0, 1, 0}, math.Pi, Vec{-1, 0, 0}},
{Vec{2, 0, 0}, Vec{0, 1, 0}, math.Pi, Vec{-2, 0, 0}},
{Vec{1, 2, 3}, Vec{1, 1, 1}, 2. / 3. * math.Pi, Vec{3, 1, 2}},
} {
got := test.v.Rotate(test.alpha, test.axis)
if !vecApproxEqual(got, test.want, tol) {
t.Errorf(
"rotate(%v, %v, %v)= %v, want=%v",
test.v, test.alpha, test.axis, got, test.want,
)
}
}
}
func vecIsNaN(v Vec) bool {
return math.IsNaN(v.X) && math.IsNaN(v.Y) && math.IsNaN(v.Z)
}
@@ -250,3 +276,12 @@ func vecEqual(a, b Vec) bool {
}
return a == b
}
func vecApproxEqual(a, b Vec, tol float64) bool {
if vecIsNaNAny(a) || vecIsNaNAny(b) {
return vecIsNaN(a) && vecIsNaN(b)
}
return scalar.EqualWithinAbs(a.X, b.X, tol) &&
scalar.EqualWithinAbs(a.Y, b.Y, tol) &&
scalar.EqualWithinAbs(a.Z, b.Z, tol)
}