add swirl

This commit is contained in:
Yongwei Xing 2021-03-04 13:59:46 +08:00
parent ee719fc631
commit c85e0b7a5c
7 changed files with 138 additions and 2 deletions

View file

@ -16,6 +16,7 @@
- Circle Loop
- Silk Sky
- Dot Line
- Swirl
For these kinds of art, the package provides as many as parameters to control the appearance.
@ -37,6 +38,8 @@ NewRandCicle(mc, msp int, minStep, maxStep, minr, maxr float64, isRandColor bool
NewSilkSky(circleNum int, sunRadius float64)
NewSilkSmoke(mc, msp int, minStep, maxStep, minRadius, maxRadius float64, isRandColor bool)
NewSpiralSquare(squareNum int, rectSide, decay float64, randColor bool)
NewSwirl(a, b, c, d, xaixs, yaixs float64)
NewDotLine(n int, ras, canv float64, randColor bool)
```
## General Options
@ -157,6 +160,23 @@ func main() {
![](images/julia.png)
### Swirl
```go
func main() {
rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(1600, 1600)
c.SetBackground(generativeart.Azure)
c.FillBackground()
c.SetForeground(color.RGBA{113, 3, 0, 180})
c.SetIterations(8000000)
c.Draw(generativeart.NewSwirl(0.970, -1.899, -1.381, -1.506, 2.0, 2.0))
c.ToPNG("swirl.png")
}
```
![](images/swirl.png)
### Circle Line
```go
@ -246,3 +266,4 @@ Thanks for the following sites and repos, I got lots of ideas, inspiration, code
- https://github.com/pkd2512/inktober2017
- http://blog.dragonlab.de/2015/03/generative-art-week-1
- https://editor.p5js.org/kenekk1/sketches/Ly-5XYvKX
- http://paulbourke.net/fractals/peterdejong/

View file

@ -45,7 +45,7 @@ func (d *dotLine) Generative(c *canva) {
newx = oldx
newy = oldy
}
if newx == oldx && rand.Intn(3) > 1 {
if newx == oldx && rand.Intn(6) > 4 {
ctex.DrawEllipse(float64(oldx)*d.ras+d.canv, float64(oldy)*d.ras+d.canv, c.opts.lineWidth, c.opts.lineWidth)
ctex.Fill()
continue

View file

@ -12,7 +12,7 @@ func main() {
c := generativeart.NewCanva(2080, 2080)
c.SetBackground(color.RGBA{230, 230, 230, 255})
c.SetLineWidth(10)
c.SetIterations(4000)
c.SetIterations(15000)
c.SetColorSchema(generativeart.Plasma)
c.FillBackground()
c.Draw(generativeart.NewDotLine(100, 20, 50, false))

19
example/example_swirl.go Normal file
View file

@ -0,0 +1,19 @@
package main
import (
"github.com/jdxyw/generativeart"
"image/color"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(1600, 1600)
c.SetBackground(generativeart.Azure)
c.FillBackground()
c.SetForeground(color.RGBA{113, 3, 0, 180})
c.SetIterations(8000000)
c.Draw(generativeart.NewSwirl(0.970, -1.899, -1.381, -1.506, 2.0, 2.0))
c.ToPNG("swirl.png")
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 760 KiB

After

Width:  |  Height:  |  Size: 773 KiB

BIN
images/swirl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 KiB

96
swirl.go Normal file
View file

@ -0,0 +1,96 @@
package generativeart
import (
"github.com/fogleman/gg"
"math"
)
type swirl struct {
// These are some math parameters.
// http://paulbourke.net/fractals/peterdejong/
a, b, c, d, xaixs, yaixs float64
}
func NewSwirl(a, b, c, d, xaixs, yaixs float64) *swirl {
return &swirl{
a: a,
b: b,
c: c,
d: d,
xaixs: xaixs,
yaixs: yaixs,
}
}
// Generative draws a swirl image.
func (s *swirl) Generative(c *canva) {
ctex := gg.NewContextForRGBA(c.img)
ctex.SetLineWidth(c.opts.lineWidth)
start := point{
x: 1.0,
y: 1.0,
}
cl := c.opts.foreground
for i := 0; i < c.opts.nIters; i++ {
next := s.swirlTransform(start)
x, y := ConvertCartesianToPixel(next.x, next.y, s.xaixs, s.yaixs, c.height, c.width)
c.img.Set(x, y, cl)
start = next
}
s.removeNoisy(c)
}
func (s *swirl) swirlTransform(p point) point {
return point{
x: math.Sin(s.a*p.y) - math.Cos(s.b*p.x),
y: math.Sin(s.c*p.x) - math.Cos(s.d*p.y),
}
}
func (s *swirl) removeNoisy(c *canva) {
for i := 1; i < c.width-1; i++ {
for j := 1; j < c.height-1; j++ {
if c.img.At(i, j) == c.opts.background {
continue
}
var n int
if c.img.At(i+1, j) == c.opts.background {
n += 1
}
if c.img.At(i+1, j+1) == c.opts.background {
n += 1
}
if c.img.At(i, j+1) == c.opts.background {
n += 1
}
if c.img.At(i-1, j) == c.opts.background {
n += 1
}
if c.img.At(i-1, j+1) == c.opts.background {
n += 1
}
if c.img.At(i-1, j-1) == c.opts.background {
n += 1
}
if c.img.At(i+1, j-1) == c.opts.background {
n += 1
}
if c.img.At(i, j-1) == c.opts.background {
n += 1
}
if n > 5 {
c.img.Set(i, j, c.opts.background)
}
}
}
}