2021-03-29 15:11:47 +00:00
|
|
|
package arts
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/jdxyw/generativeart"
|
|
|
|
"github.com/jdxyw/generativeart/common"
|
2021-03-30 02:49:33 +00:00
|
|
|
"image/color"
|
2021-03-29 15:11:47 +00:00
|
|
|
)
|
|
|
|
|
2021-03-30 02:49:33 +00:00
|
|
|
// ColorMapping maps some parameters to color space.
|
|
|
|
type ColorMapping func(float64, float64, float64) color.RGBA
|
|
|
|
|
2021-03-29 15:11:47 +00:00
|
|
|
type domainWrap struct {
|
|
|
|
noise *common.PerlinNoise
|
|
|
|
scale float64
|
2021-03-30 09:10:04 +00:00
|
|
|
scale2 float64
|
2021-03-29 15:11:47 +00:00
|
|
|
xOffset, yOffset float64
|
2021-03-30 02:49:33 +00:00
|
|
|
fn ColorMapping
|
2021-03-29 15:11:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewDomainWrap returns a domainWrap object.
|
2021-03-30 09:10:04 +00:00
|
|
|
func NewDomainWrap(scale, scale2, xOffset, yOffset float64, cmap ColorMapping) *domainWrap {
|
2021-03-29 15:11:47 +00:00
|
|
|
return &domainWrap{
|
|
|
|
scale: scale,
|
2021-03-30 09:10:04 +00:00
|
|
|
scale2: scale2,
|
2021-03-29 15:11:47 +00:00
|
|
|
xOffset: xOffset,
|
|
|
|
yOffset: yOffset,
|
|
|
|
noise: common.NewPerlinNoise(),
|
2021-03-30 02:49:33 +00:00
|
|
|
fn: cmap,
|
2021-03-29 15:11:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generative draws a domain warp image.
|
|
|
|
// Reference: https://www.iquilezles.org/www/articles/warp/warp.htm
|
|
|
|
func (d *domainWrap) Generative(c *generativeart.Canva) {
|
|
|
|
for h := 0.0; h < float64(c.Height()); h += 1.0 {
|
2021-03-30 02:49:33 +00:00
|
|
|
for w := 0.0; w < float64(c.Width()); w += 1.0 {
|
|
|
|
r, m1, m2 := d.pattern(w*d.scale, h*d.scale, d.xOffset, d.yOffset)
|
|
|
|
rgb := d.fn(r, m1, m2)
|
|
|
|
c.Img().Set(int(w), int(h), rgb)
|
2021-03-29 15:11:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *domainWrap) pattern(x, y, xOffest, yOffset float64) (float64, float64, float64) {
|
|
|
|
qx := d.fbm(x+xOffest, y+yOffset)
|
|
|
|
qy := d.fbm(x+xOffest+5.2, y+yOffset+1.3)
|
|
|
|
|
2021-03-30 09:10:04 +00:00
|
|
|
rx := d.fbm(x+d.scale2*qx+1.7, y+d.scale2*qy+9.2)
|
|
|
|
ry := d.fbm(x+d.scale2*qx+8.3, y+d.scale2*qy+2.8)
|
2021-03-29 15:11:47 +00:00
|
|
|
|
2021-03-30 09:10:04 +00:00
|
|
|
return d.fbm(qx+d.scale2*rx, qy+d.scale2*ry), common.Magnitude(qx, qy), common.Magnitude(rx, ry)
|
2021-03-29 15:11:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (d *domainWrap) fbm(x, y float64) float64 {
|
|
|
|
return d.noise.Noise2D(x, y)
|
|
|
|
}
|