mirror of https://github.com/statping/statping
				
				
				
			
		
			
				
	
	
		
			119 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
package utils
 | 
						|
 | 
						|
import (
 | 
						|
	"math"
 | 
						|
	"math/rand"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	B  = 0x100
 | 
						|
	N  = 0x1000
 | 
						|
	BM = 0xff
 | 
						|
)
 | 
						|
 | 
						|
func NewPerlin(alpha, beta float64, n int, seed int64) *Perlin {
 | 
						|
	return NewPerlinRandSource(alpha, beta, n, rand.NewSource(seed))
 | 
						|
}
 | 
						|
 | 
						|
// Perlin is the noise generator
 | 
						|
type Perlin struct {
 | 
						|
	alpha float64
 | 
						|
	beta  float64
 | 
						|
	n     int
 | 
						|
 | 
						|
	p  [B + B + 2]int
 | 
						|
	g3 [B + B + 2][3]float64
 | 
						|
	g2 [B + B + 2][2]float64
 | 
						|
	g1 [B + B + 2]float64
 | 
						|
}
 | 
						|
 | 
						|
func NewPerlinRandSource(alpha, beta float64, n int, source rand.Source) *Perlin {
 | 
						|
	var p Perlin
 | 
						|
	var i int
 | 
						|
 | 
						|
	p.alpha = alpha
 | 
						|
	p.beta = beta
 | 
						|
	p.n = n
 | 
						|
 | 
						|
	r := rand.New(source)
 | 
						|
 | 
						|
	for i = 0; i < B; i++ {
 | 
						|
		p.p[i] = i
 | 
						|
		p.g1[i] = float64((r.Int()%(B+B))-B) / B
 | 
						|
 | 
						|
		for j := 0; j < 2; j++ {
 | 
						|
			p.g2[i][j] = float64((r.Int()%(B+B))-B) / B
 | 
						|
		}
 | 
						|
 | 
						|
		normalize2(&p.g2[i])
 | 
						|
	}
 | 
						|
 | 
						|
	for ; i > 0; i-- {
 | 
						|
		k := p.p[i]
 | 
						|
		j := r.Int() % B
 | 
						|
		p.p[i] = p.p[j]
 | 
						|
		p.p[j] = k
 | 
						|
	}
 | 
						|
 | 
						|
	for i := 0; i < B+2; i++ {
 | 
						|
		p.p[B+i] = p.p[i]
 | 
						|
		p.g1[B+i] = p.g1[i]
 | 
						|
		for j := 0; j < 2; j++ {
 | 
						|
			p.g2[B+i][j] = p.g2[i][j]
 | 
						|
		}
 | 
						|
		for j := 0; j < 3; j++ {
 | 
						|
			p.g3[B+i][j] = p.g3[i][j]
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return &p
 | 
						|
}
 | 
						|
 | 
						|
func normalize2(v *[2]float64) {
 | 
						|
	s := math.Sqrt(v[0]*v[0] + v[1]*v[1])
 | 
						|
	v[0] = v[0] / s
 | 
						|
	v[1] = v[1] / s
 | 
						|
}
 | 
						|
 | 
						|
func (p *Perlin) Noise1D(x float64) float64 {
 | 
						|
	var scale float64 = 1
 | 
						|
	var sum float64
 | 
						|
	px := x
 | 
						|
 | 
						|
	for i := 0; i < p.n; i++ {
 | 
						|
		val := p.noise1(px)
 | 
						|
		sum += val / scale
 | 
						|
		scale *= p.alpha
 | 
						|
		px *= p.beta
 | 
						|
	}
 | 
						|
	if sum < 0 {
 | 
						|
		sum = sum * -1
 | 
						|
	}
 | 
						|
	return sum
 | 
						|
}
 | 
						|
 | 
						|
func (p *Perlin) noise1(arg float64) float64 {
 | 
						|
	var vec [1]float64
 | 
						|
	vec[0] = arg
 | 
						|
 | 
						|
	t := vec[0] + N
 | 
						|
	bx0 := int(t) & BM
 | 
						|
	bx1 := (bx0 + 1) & BM
 | 
						|
	rx0 := t - float64(int(t))
 | 
						|
	rx1 := rx0 - 1.
 | 
						|
 | 
						|
	sx := sCurve(rx0)
 | 
						|
	u := rx0 * p.g1[p.p[bx0]]
 | 
						|
	v := rx1 * p.g1[p.p[bx1]]
 | 
						|
 | 
						|
	return lerp(sx, u, v)
 | 
						|
}
 | 
						|
 | 
						|
func sCurve(t float64) float64 {
 | 
						|
	return t * t * (3. - 2.*t)
 | 
						|
}
 | 
						|
 | 
						|
func lerp(t, a, b float64) float64 {
 | 
						|
	return a + t*(b-a)
 | 
						|
}
 |