generativeart/arts/domainwrap.go

90 lines
2.4 KiB
Go
Raw Permalink Normal View History

2021-03-29 15:11:47 +00:00
package arts
import (
"fmt"
2021-03-29 15:11:47 +00:00
"github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
2021-03-30 02:49:33 +00:00
"image/color"
"log"
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-04-07 09:22:53 +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
// How many images would be created in this generation.
numImages int
// Use these parameters to create images with time lapse.
xOffsetStep, yOffsetStep float64
// The imagPath for generative images.
imgPath string
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-04-07 09:22:53 +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
}
}
func (d *domainWrap) SetDynamicParameter(xstep, ystep float64, n int, path string) {
d.xOffsetStep = xstep
d.yOffsetStep = ystep
d.numImages = n
d.imgPath = path
}
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) {
if d.numImages == 0 && len(d.imgPath) == 0 {
d.generative(c)
return
}
if d.numImages > 0 && len(d.imgPath) == 0 {
log.Fatal("Missing the parameters numImages or imgPath")
}
for i := 0; i < d.numImages; i++ {
imgfile := fmt.Sprintf("%v/domainwrap%03d.PNG", d.imgPath, i)
d.xOffset += d.xOffsetStep * float64(i)
d.yOffset += d.yOffsetStep * float64(i)
d.generative(c)
c.ToPNG(imgfile)
}
}
func (d *domainWrap) generative(c *generativeart.Canva) {
2021-03-29 15:11:47 +00:00
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)
}