init
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
package world
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"wh/config"
|
||||
"wh/fixed"
|
||||
)
|
||||
|
||||
func TestOrbitsAreCirclesAtCommonSpeed(t *testing.T) {
|
||||
cfg := config.Default()
|
||||
asts, _ := Generate(cfg)
|
||||
want := cfg.OrbitSpeed.Float64()
|
||||
for _, a := range asts {
|
||||
o := a.Orbit
|
||||
for _, ts := range []int64{0, 100_000, 777_777, o.Period / 3, o.Period - 1} {
|
||||
p, v := o.State(ts)
|
||||
if r := p.Len().Float64(); math.Abs(r-o.A.Float64()) > 1e-3 {
|
||||
t.Fatalf("asteroid %d t=%d: radius %g, want %g", a.ID, ts, r, o.A.Float64())
|
||||
}
|
||||
if s := v.Len().Float64(); math.Abs(s-want)/want > 1e-5 {
|
||||
t.Fatalf("asteroid %d t=%d: speed %g, want %g", a.ID, ts, s, want)
|
||||
}
|
||||
if d := p.Dot(v).Float64() / (p.Len().Float64() * want); math.Abs(d) > 1e-4 {
|
||||
t.Fatalf("asteroid %d: velocity not tangent (cos=%g)", a.ID, d)
|
||||
}
|
||||
// Inclination bounds the height above the ecliptic.
|
||||
if z := p.Z.Abs().Float64(); z > o.A.Float64()*math.Sin(o.Inc.Float64())*1.001+1e-3 {
|
||||
t.Fatalf("asteroid %d: |z|=%g exceeds inclination bound", a.ID, z)
|
||||
}
|
||||
}
|
||||
// Periodic.
|
||||
p1, _ := o.State(12345)
|
||||
p2, _ := o.State(12345 + o.Period)
|
||||
if d := p1.Sub(p2).Len().Float64(); d > 1 {
|
||||
t.Fatalf("asteroid %d not periodic, off by %g km", a.ID, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrbitPlaneMatchesInclination(t *testing.T) {
|
||||
o := Orbit{A: fixed.FromInt(2_000_000), Inc: fixed.FromRatio(3, 10), Node: fixed.FromInt(2)}
|
||||
o.Period = PeriodFor(o.A, fixed.FromInt(3))
|
||||
// The orbit normal is Rz(Node)Rx(Inc) applied to +Z; positions must be
|
||||
// perpendicular to it, and the maximum height is A*sin(Inc).
|
||||
n := fixed.Vec{Z: fixed.One}.RotateX(o.Inc).RotateZ(o.Node)
|
||||
var maxZ float64
|
||||
for k := int64(0); k < 50; k++ {
|
||||
p, _ := o.State(k * o.Period / 50)
|
||||
if d := p.Dot(n).Float64(); math.Abs(d) > 1e-2 {
|
||||
t.Fatalf("position not in the orbital plane: p.n = %g", d)
|
||||
}
|
||||
maxZ = math.Max(maxZ, p.Z.Float64())
|
||||
}
|
||||
if want := o.A.Float64() * math.Sin(0.3); math.Abs(maxZ-want)/want > 0.01 {
|
||||
t.Fatalf("max z = %g, want %g", maxZ, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateDeterministic(t *testing.T) {
|
||||
cfg := config.Default()
|
||||
a1, s1 := Generate(cfg)
|
||||
a2, s2 := Generate(cfg)
|
||||
if len(a1) != cfg.AsteroidCount || s1 != s2 {
|
||||
t.Fatal("mismatch")
|
||||
}
|
||||
for i := range a1 {
|
||||
if a1[i] != a2[i] {
|
||||
t.Fatalf("asteroid %d differs", i)
|
||||
}
|
||||
}
|
||||
cfg.Seed = 2
|
||||
a3, _ := Generate(cfg)
|
||||
if a3[0] == a1[0] {
|
||||
t.Fatal("different seeds should differ")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user