func (p smoothDiverging) Palette(n int) palette.Palette {
	if p.Max() == 0 && p.Min() == 0 {
		p.SetMin(0)
		p.SetMax(1)
	}
	delta := (p.max - p.min) / float64(n-1)
	c := make([]color.Color, n)
	for i := range c {
		v := p.min + delta*float64(i)
		var err error
		c[i], err = p.At(v)
		if err != nil {
			panic(err)
		}
	}
	return plte(c)
}
Palette returns a palette.Palette with the specified number of colors.
package moreland
import (
	"fmt"
	"image/color"
	"math"
	"gonum.org/v1/plot/palette"
)
type smoothDiverging struct {
	start, end msh
	convergeM float64
	alpha float64
	min, max float64
	convergePoint float64
}
func NewSmoothDiverging(start, end color.Color, convergeM float64) palette.DivergingColorMap {
	return newSmoothDiverging(colorToMSH(start), colorToMSH(end), convergeM)
}
func newSmoothDiverging(start, end msh, convergeM float64) palette.DivergingColorMap {
	return &smoothDiverging{
		start:         start,
		end:           end,
		convergeM:     convergeM,
		convergePoint: math.NaN(),
		alpha:         1,
	}
}
func (p *smoothDiverging) At(v float64) (color.Color, error) {
	if err := checkRange(p.min, p.max, v); err != nil {
		return nil, err
	}
	convergePoint := (p.convergePoint - p.min) / (p.max - p.min)
	scalar := (v - p.min) / (p.max - p.min)
	o := p.interpolateMSHDiverging(scalar, convergePoint).cieLAB().cieXYZ().rgb().sRGBA(p.alpha)
	if !inUnitRange(o.R) || !inUnitRange(o.G) || !inUnitRange(o.B) || !inUnitRange(o.A) {
		return nil, fmt.Errorf("moreland: invalid color r:%g, g:%g, b:%g, a:%g", o.R, o.G, o.B, o.A)
	}
	return o, nil
}
func inUnitRange(v float64) bool { return 0 <= v && v <= 1 }
func (p *smoothDiverging) SetMax(v float64) {
	p.max = v
	p.convergePoint = (p.min + p.max) / 2
}
func (p *smoothDiverging) SetMin(v float64) {
	p.min = v
	p.convergePoint = (p.min + p.max) / 2
}
func (p *smoothDiverging) Max() float64 {
	return p.max
}
func (p *smoothDiverging) Min() float64 {
	return p.min
}
func (p *smoothDiverging) SetAlpha(alpha float64) {
	if !inUnitRange(alpha) {
		panic(fmt.Errorf("invalid alpha: %g", alpha))
	}
	p.alpha = alpha
}
func (p *smoothDiverging) Alpha() float64 {
	return p.alpha
}
func (p *smoothDiverging) SetConvergePoint(val float64) {
	if val > p.Max() || val < p.Min() {
		panic(fmt.Errorf("moreland: convergence point (%g) must be between min (%g) and max (%g)",
			val, p.Min(), p.Max()))
	}
	p.convergePoint = val
}
func (p *smoothDiverging) ConvergePoint() float64 {
	return p.convergePoint
}
func (p *smoothDiverging) interpolateMSHDiverging(scalar, convergePoint float64) msh {
	startHTwist := hueTwist(p.start, p.convergeM)
	endHTwist := hueTwist(p.end, p.convergeM)
	if scalar < convergePoint {
		interp := scalar / convergePoint
		return msh{
			M: (p.convergeM-p.start.M)*interp + p.start.M,
			S: p.start.S * (1 - interp),
			H: p.start.H + startHTwist*interp,
		}
	}
	interp1 := (scalar - 1) / (convergePoint - 1)
	interp2 := (scalar/convergePoint - 1)
	var H float64
	if scalar > convergePoint {
		H = p.end.H + endHTwist*interp1
	}
	return msh{
		M: (p.convergeM-p.end.M)*interp1 + p.end.M,
		S: p.end.S * interp2,
		H: H,
	}
}