-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
sharp.go
100 lines (87 loc) · 1.48 KB
/
sharp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package colorgrad
import (
"math"
"github.com/lucasb-eyer/go-colorful"
)
type sharpGradient struct {
colors []colorful.Color
pos []float64
last int
dmin float64
dmax float64
}
func (sg sharpGradient) At(t float64) colorful.Color {
if t <= sg.dmin {
return sg.colors[0]
}
if t >= sg.dmax {
return sg.colors[sg.last]
}
if math.IsNaN(t) {
return colorful.Color{R: 0, G: 0, B: 0}
}
low := 0
high := len(sg.pos)
for low < high {
mid := (low + high) / 2
if sg.pos[mid] < t {
low = mid + 1
} else {
high = mid
}
}
if low == 0 {
low = 1
}
i := low - 1
p1 := sg.pos[i]
p2 := sg.pos[low]
if i%2 == 0 {
return sg.colors[i]
}
t = (t - p1) / (p2 - p1)
a := sg.colors[i]
b := sg.colors[low]
return a.BlendRgb(b, t)
}
func newSharpGradient(colorsIn []colorful.Color, dmin, dmax float64, smoothness float64) Gradient {
n := len(colorsIn)
colors := make([]colorful.Color, n*2)
i := 0
for _, c := range colorsIn {
colors[i] = c
i++
colors[i] = c
i++
}
t := clamp01(smoothness) * (dmax - dmin) / float64(n) / 4
p := linspace(dmin, dmax, uint(n+1))
pos := make([]float64, n*2)
i = 0
j := 0
for x := 0; x < int(n); x++ {
pos[i] = p[j]
if i > 0 {
pos[i] += t
}
i++
j++
pos[i] = p[j]
if i < len(colors)-1 {
pos[i] -= t
}
i++
}
gradbase := sharpGradient{
colors: colors,
pos: pos,
last: int(n*2 - 1),
dmin: dmin,
dmax: dmax,
}
return Gradient{
grad: gradbase,
dmin: dmin,
dmax: dmax,
}
}