add domain warp

This commit is contained in:
Yongwei Xing 2021-03-30 10:49:33 +08:00
parent ad70fe805b
commit 471e3eb992
6 changed files with 88 additions and 7 deletions

View file

@ -31,6 +31,7 @@
- [Dot Line](#dot-line) - [Dot Line](#dot-line)
- [Ocean Fish](#ocean-fish) - [Ocean Fish](#ocean-fish)
- [Circle Loop](#circle-loop) - [Circle Loop](#circle-loop)
- [Domain Warp](#domain-warp)
- [Circle Noise](#circle-noise) - [Circle Noise](#circle-noise)
- [Color Canva](#color-canva) - [Color Canva](#color-canva)
- [Julia Set](#julia-set) - [Julia Set](#julia-set)
@ -81,6 +82,7 @@ This package is still working in progress. More types would be added. Welcome an
- Yarn - Yarn
- Black Hole - Black Hole
- Color Canva - Color Canva
- Domain Warp
For these kinds of art, the package provides as many parameters to control the appearance. For these kinds of art, the package provides as many parameters to control the appearance.
@ -120,6 +122,7 @@ NewCircleNoise(dotsN, colorMin, colorMax int)
NewYarn(n int) NewYarn(n int)
NewBlackHole(circleN int, density, circleGap float64) NewBlackHole(circleN int, density, circleGap float64)
NewColorCanve(seg float64) NewColorCanve(seg float64)
NewDomainWrap(scale, xOffset, yOffset float64, cmap ColorMapping)
``` ```
## Docs ## Docs
@ -414,6 +417,31 @@ func main() {
![](images/circleloop.png) ![](images/circleloop.png)
### Domain Warp
```go
func cmap(r, m1, m2 float64) color.RGBA {
rgb := color.RGBA{
uint8(common.Constrain(m1*255*r, 0, 255)),
uint8(common.Constrain(r*200, 0, 255)),
uint8(common.Constrain(m2*255*r, 70, 255)),
255,
}
return rgb
}
func main() {
rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500)
c.SetBackground(common.Black)
c.FillBackground()
c.Draw(arts.NewDomainWrap(0.01, 4, 8, cmap))
c.ToPNG("domainwarp.png")
}
```
![](images/domainwarp.png)
### Circle Noise ### Circle Noise
```go ```go

View file

@ -1,35 +1,40 @@
package arts package arts
import ( import (
"github.com/fogleman/gg"
"github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common" "github.com/jdxyw/generativeart/common"
"image/color"
) )
// ColorMapping maps some parameters to color space.
type ColorMapping func(float64, float64, float64) color.RGBA
type domainWrap struct { type domainWrap struct {
noise *common.PerlinNoise noise *common.PerlinNoise
scale float64 scale float64
xOffset, yOffset float64 xOffset, yOffset float64
fn ColorMapping
} }
// NewDomainWrap returns a domainWrap object. // NewDomainWrap returns a domainWrap object.
func NewDomainWrap(scale, xOffset, yOffset float64) *domainWrap { func NewDomainWrap(scale, xOffset, yOffset float64, cmap ColorMapping) *domainWrap {
return &domainWrap{ return &domainWrap{
scale: scale, scale: scale,
xOffset: xOffset, xOffset: xOffset,
yOffset: yOffset, yOffset: yOffset,
noise: common.NewPerlinNoise(), noise: common.NewPerlinNoise(),
fn: cmap,
} }
} }
// Generative draws a domain warp image. // Generative draws a domain warp image.
// Reference: https://www.iquilezles.org/www/articles/warp/warp.htm // Reference: https://www.iquilezles.org/www/articles/warp/warp.htm
func (d *domainWrap) Generative(c *generativeart.Canva) { func (d *domainWrap) Generative(c *generativeart.Canva) {
_ = gg.NewContextForRGBA(c.Img())
for h := 0.0; h < float64(c.Height()); h += 1.0 { for h := 0.0; h < float64(c.Height()); h += 1.0 {
for w := 0.0; h < float64(c.Width()); h += 1.0 { for w := 0.0; w < float64(c.Width()); w += 1.0 {
_, _, _ = d.pattern(w*d.scale, h*d.scale, d.xOffset, d.yOffset) 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)
} }
} }
} }

View file

@ -36,6 +36,8 @@
- [parameters](#parameters-15) - [parameters](#parameters-15)
- [Color Canva](#color-canva) - [Color Canva](#color-canva)
- [parameters](#parameters-16) - [parameters](#parameters-16)
- [Domain Warping](#domain-warping)
- [parameters](#parameters-17)
## Color Circle 2 ## Color Circle 2
@ -263,3 +265,20 @@ cc := arts.NewColorCanve(5)
``` ```
![](../images/colorcanva.png) ![](../images/colorcanva.png)
## Domain Warping
Warping, or domain distortion is a very common technique in computer graphics for generating procedural textures and geometry. It's often used to pinch an object, stretch it, twist it, bend it, make it thicker or apply any deformation you want.
### parameters
- scale: Control the noise generator.
- xOffset: Control the noise generator.
- yOffset: Control the noise generator.
- fn: A function to mapping the `noise` to color.
```go
d := arts.NewDomainWrap(0.01, 4, 8, cmap)
```
![](../images/domainwarp.png)

View file

@ -0,0 +1,29 @@
package main
import (
"github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/arts"
"github.com/jdxyw/generativeart/common"
"image/color"
"math/rand"
"time"
)
func cmap(r, m1, m2 float64) color.RGBA {
rgb := color.RGBA{
uint8(common.Constrain(m1*255*r, 0, 255)),
uint8(common.Constrain(r*200, 0, 255)),
uint8(common.Constrain(m2*255*r, 70, 255)),
255,
}
return rgb
}
func main() {
rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500)
c.SetBackground(common.Black)
c.FillBackground()
c.Draw(arts.NewDomainWrap(0.01, 4, 8, cmap))
c.ToPNG("domainwarp.png")
}

View file

@ -20,7 +20,7 @@ func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500) c := generativeart.NewCanva(500, 500)
c.SetIterations(800) c.SetIterations(800)
c.SetColorSchema(common.Viridis) c.SetColorSchema(common.Citrus)
c.FillBackground() c.FillBackground()
c.Draw(arts.NewJulia(julia1, 40, 1.5, 1.5)) c.Draw(arts.NewJulia(julia1, 40, 1.5, 1.5))
c.ToPNG("julia.png") c.ToPNG("julia.png")

BIN
images/domainwarp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB