fixed end-slope splines

This commit is contained in:
Josh Deprez 2021-10-04 13:33:35 +11:00
parent 22cb55de15
commit d28762468f
3 changed files with 28 additions and 31 deletions

View file

@ -22,21 +22,18 @@ func main() {
{X: 3, Y: -2},
{X: 4, Y: 4},
}
linear := &geom.LinearSpline{Points: points}
if err := linear.Prepare(); err != nil {
log.Fatalf("linear.Prepare() = %v, want nil", err)
}
cubic := &geom.CubicSpline{Points: points,
cubic := &geom.CubicSpline{
Points: points,
FixedPreslope: true,
FixedPostslope: false,
FixedPostslope: true,
Preslope: -5,
//Postslope: -4,
Postslope: -4,
}
if err := cubic.Prepare(); err != nil {
log.Fatalf("cubic.Prepare() = %v, want nil", err)
}
// Produce interpolated points in CSV-like form.
for x := -8.0; x < 8.0; x += 0.0625 {
fmt.Printf("%f,%f,%f\n", x, linear.Interpolate(x), cubic.Interpolate(x))
fmt.Printf("%f,%f\n", x, cubic.Interpolate(x))
}
}

View file

@ -208,7 +208,7 @@ func (s *CubicSpline) Prepare() error {
s.m[i] = (B[i] - s.h[i]*s.m[i+1]) / diag[i]
}
if s.FixedPreslope {
s.m[0] = (B[0] - s.h[0]*s.m[1]) / diag[1]
s.m[0] = (B[0] - s.h[0]*s.m[1]) / diag[0]
}
// Derive pre- and post-slope, if not fixed:
if !s.FixedPreslope {

View file

@ -162,8 +162,8 @@ func TestFixedEndSlopesCubicSpline(t *testing.T) {
Points: []Float2{{-7, -2}, {-5, 1}, {-3, 0}, {-2, -3}, {0, 2}, {1, -5}, {3, -2}, {4, 4}},
FixedPreslope: true,
FixedPostslope: true,
Preslope: -1,
Postslope: 1,
Preslope: -5,
Postslope: 4,
}
if err := s.Prepare(); err != nil {
t.Errorf("s.Prepare() = %v, want nil", err)
@ -171,34 +171,34 @@ func TestFixedEndSlopesCubicSpline(t *testing.T) {
tests := []struct {
x, want float64
}{
{x: -8, want: -3.648342225609756},
{x: -7.5, want: -2.824171112804878},
{x: -8, want: 3},
{x: -7.5, want: 0.5},
{x: -7, want: -2},
{x: -6.5, want: -1.180464581745427},
{x: -6, want: -0.3887433307926829},
{x: -5.5, want: 0.3473495855564025},
{x: -6.5, want: -3.213753455247408},
{x: -6, want: -2.4866758806597526},
{x: -5.5, want: -0.7662603657422216},
{x: -5, want: 1},
{x: -4.5, want: 1.5067079125381098},
{x: -4, want: 1.6662299923780488},
{x: -3.5, want: 1.2426370760289636},
{x: -4.5, want: 2.02752418673185},
{x: -4, want: 2.183379403298762},
{x: -3.5, want: 1.4975449182162928},
{x: -3, want: 0},
{x: -2.5, want: -1.9368449885670733},
{x: -2.5, want: -1.9904880751130807},
{x: -2, want: -3},
{x: -1.5, want: -1.855450886051829},
{x: -1, want: 0.45221989329268286},
{x: -0.5, want: 2.2837807259908534},
{x: -1.5, want: -1.8287325238726178},
{x: -1, want: 0.4715013478320472},
{x: -0.5, want: 2.2859845456206873},
{x: 0, want: 2},
{x: 0.5, want: -1.229539824695122},
{x: 0.5, want: -1.2096392835930003},
{x: 1, want: -5},
{x: 1.5, want: -6.734946646341463},
{x: 2, want: -6.406821646341463},
{x: 2.5, want: -4.6252858231707314},
{x: 1.5, want: -6.8416283067574355},
{x: 2, want: -6.6251085119020425},
{x: 2.5, want: -4.846034461095628},
{x: 3, want: -2},
{x: 3.5, want: 0.941477705792683},
{x: 3.5, want: 1.3035791794215745},
{x: 4, want: 4},
{x: 4.5, want: 7.078029725609756},
{x: 5, want: 10.156059451219512},
{x: 5.5, want: 13.234089176829269},
{x: 4.5, want: 6},
{x: 5, want: 8},
{x: 5.5, want: 10},
}
for _, test := range tests {
if got := s.Interpolate(test.x); math.Abs(got-test.want) > 0.0000001 {