Skip to content

Commit ba6ce98

Browse files
author
Elli Beres
committed
Initial commit
0 parents  commit ba6ce98

File tree

7 files changed

+226
-0
lines changed

7 files changed

+226
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.vscode
2+
.DS_Store
3+

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# 2D OpenSimplex Noise
2+
3+
Ported from Python implementation [here](https://github.com/lmas/opensimplex).
4+
5+
## IMPORTANT
6+
7+
For actual production code, use [this port](https://github.com/ojrac/opensimplex-go) instead.

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module github.com/ellifteria/opensimplex2-go
2+
3+
go 1.20
4+
5+
require github.com/ojrac/opensimplex-go v1.0.2

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/ojrac/opensimplex-go v1.0.2 h1:l4vs0D+JCakcu5OV0kJ99oEaWJfggSc9jiLpxaWvSzs=
2+
github.com/ojrac/opensimplex-go v1.0.2/go.mod h1:NwbXFFbXcdGgIFdiA7/REME+7n/lOf1TuEbLiZYOWnM=

opensimplex2.go

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package opensimplex2
2+
3+
import "math"
4+
5+
type Noise interface {
6+
Noise2D(x, y float64) float64
7+
}
8+
9+
type noise struct {
10+
perm []int16
11+
}
12+
13+
func NewNoise(seed int64) Noise {
14+
n := &noise{perm: make([]int16, 256)}
15+
16+
var source [256]int16
17+
18+
for i := range source {
19+
source[i] = int16(i)
20+
}
21+
22+
seed = seed*6364136223846793005 + 1442695040888963407
23+
seed = seed*6364136223846793005 + 1442695040888963407
24+
seed = seed*6364136223846793005 + 1442695040888963407
25+
26+
var i int32
27+
for i = 255; i >= 0; i-- {
28+
seed = seed*6364136223846793005 + 1442695040888963407
29+
r := int32((seed + 31) % int64(i+1))
30+
if r < 0 {
31+
r += i + 1
32+
}
33+
34+
n.perm[i] = source[r]
35+
source[r] = source[i]
36+
}
37+
38+
return n
39+
}
40+
41+
func (n *noise) Noise2D(x, y float64) float64 {
42+
43+
var noisyValue float64
44+
45+
stretchOffset := (x + y) * StretchConstant2
46+
xs := x + stretchOffset
47+
ys := y + stretchOffset
48+
49+
xsb := math.Floor(xs)
50+
ysb := math.Floor(ys)
51+
52+
squishOffset := (xsb + ysb) * SquishConstant2
53+
xb := xsb + squishOffset
54+
yb := ysb + squishOffset
55+
56+
xins := xs - xsb
57+
yins := ys - ysb
58+
59+
inSum := xins + yins
60+
61+
dx0 := x - xb
62+
dy0 := y - yb
63+
64+
var value float64 = 0.0
65+
66+
dx1 := dx0 - 1 - SquishConstant2
67+
dy1 := dy0 - 0 - SquishConstant2
68+
attn1 := 2 - dx1*dx1 - dy1*dy1
69+
if attn1 > 0 {
70+
attn1 *= attn1
71+
value += attn1 * attn1 * extrapolate2(n.perm[:], xsb+1, ysb+0, dx1, dy1)
72+
}
73+
74+
dx2 := dx0 - 0 - SquishConstant2
75+
dy2 := dy0 - 1 - SquishConstant2
76+
attn2 := 2 - dx2*dx2 - dy2*dy2
77+
if attn2 > 0 {
78+
attn2 *= attn2
79+
value += attn2 * attn2 * extrapolate2(n.perm[:], xsb+0, ysb+1, dx2, dy2)
80+
}
81+
82+
var xsvExt, ysvExt, dxExt, dyExt float64
83+
if inSum <= 1 {
84+
zins := 1 - inSum
85+
if zins > xins || zins > yins {
86+
if xins > yins {
87+
xsvExt = xsb + 1
88+
ysvExt = ysb - 1
89+
dxExt = dx0 - 1
90+
dyExt = dy0 + 1
91+
} else {
92+
xsvExt = xsb - 1
93+
ysvExt = ysb + 1
94+
dxExt = dx0 + 1
95+
dyExt = dy0 - 1
96+
}
97+
} else {
98+
xsvExt = xb + 1
99+
ysvExt = ysb + 1
100+
dxExt = dx0 - 1 - 2*SquishConstant2
101+
dyExt = dy0 - 1 - 2*SquishConstant2
102+
}
103+
} else {
104+
zins := 2 - inSum
105+
if zins < xins || zins < yins {
106+
if xins > yins {
107+
xsvExt = xsb + 2
108+
ysvExt = ysb + 0
109+
dxExt = dx0 - 2 - 2*SquishConstant2
110+
dyExt = dy0 + 0 - 2*SquishConstant2
111+
} else {
112+
xsvExt = xsb + 0
113+
ysvExt = ysb + 2
114+
dxExt = dx0 + 0 - 2*SquishConstant2
115+
dyExt = dy0 - 2 - 2*SquishConstant2
116+
}
117+
} else {
118+
xsvExt = xsb
119+
ysvExt = ysb
120+
dxExt = dx0
121+
dyExt = dy0
122+
}
123+
124+
xsb += 1
125+
ysb += 1
126+
dx0 = dx0 - 1 - 2*SquishConstant2
127+
dy0 = dy0 - 1 - 2*SquishConstant2
128+
}
129+
130+
attn0 := 2 - dx0*dx0 - dy0*dy0
131+
if attn0 > 0 {
132+
attn0 *= attn0
133+
value += attn0 * attn0 * extrapolate2(n.perm[:], xsb, ysb, dx0, dy0)
134+
}
135+
136+
attnExt := 2 - dxExt*dxExt - dyExt*dyExt
137+
if attnExt > 0 {
138+
attnExt *= attnExt
139+
value += attnExt * attnExt * extrapolate2(n.perm[:], xsvExt, ysvExt, dxExt, dyExt)
140+
}
141+
142+
noisyValue = value / NormConstant2
143+
144+
return noisyValue
145+
}
146+
147+
func extrapolate2(perm []int16, xsb, ysb, dx, dy float64) float64 {
148+
index := perm[(int32(perm[int32(xsb)&0xff])+int32(ysb))&0xff] & 0x0e
149+
g1 := float64(Gradients2[index])
150+
g2 := float64(Gradients2[index+1])
151+
152+
return g1*dx + g2*dy
153+
}

opensimplex2_constants.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package opensimplex2
2+
3+
const (
4+
StretchConstant2 float64 = -0.21132486540518708
5+
SquishConstant2 float64 = 0.3660254037844386
6+
NormConstant2 float64 = 47
7+
)
8+
9+
var Gradients2 [16]int8 = [16]int8{
10+
5, 2, 2, 5,
11+
-5, 2, -2, 5,
12+
5, -2, 2, -5,
13+
-5, -2, -2, -5,
14+
}

opensimplex2_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package opensimplex2
2+
3+
import (
4+
"math"
5+
"testing"
6+
7+
"github.com/ojrac/opensimplex-go"
8+
)
9+
10+
func TestConstants(t *testing.T) {
11+
trueStretch := (1.0/math.Sqrt(2.0+1.0) - 1.0) / 2.0
12+
trueSquish := (math.Sqrt(2.0+1.0) - 1.0) / 2.0
13+
tolerance := math.Pow10(-14)
14+
15+
if math.Abs(StretchConstant2-trueStretch) > tolerance {
16+
t.Errorf("Stretch constant incorrect; got %f, expected %f",
17+
StretchConstant2, trueStretch)
18+
}
19+
20+
if math.Abs(SquishConstant2-trueSquish) > tolerance {
21+
t.Errorf("Squish constant incorrect; got %f, expected %f",
22+
SquishConstant2, trueSquish)
23+
}
24+
}
25+
26+
func TestNoise2D(t *testing.T) {
27+
var seed int64 = 298610
28+
x, y := 14.0, 12.0
29+
tolerance := math.Pow10(-14)
30+
31+
testNoise := NewNoise(seed)
32+
testValue := testNoise.Noise2D(x, y)
33+
34+
libNoise := opensimplex.New(seed)
35+
libValue := libNoise.Eval2(x, y)
36+
37+
if math.Abs(testValue-libValue) > tolerance {
38+
t.Errorf("Inconsistent noise result; got %f, expected %f",
39+
testValue, libValue)
40+
}
41+
42+
}

0 commit comments

Comments
 (0)