diff --git a/README.md b/README.md index b963446..0c240ab 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,8 @@ - [Noise Line](#noise-line) - [Dot Line](#dot-line) - [Ocean Fish](#ocean-fish) - - [Silk Smoke](#silk-smoke) - [Circle Loop](#circle-loop) + - [Circle Noise](#circle-noise) - [Julia Set](#julia-set) - [Silk Sky](#silk-sky) - [Circle Move](#circle-move) @@ -70,6 +70,7 @@ This package is still working in progress. More types would be added. Welcome an - Pixel Hole - Dots Wave - Circle Move +- Circle Noise For these kinds of art, the package provides as many parameters to control the appearance. @@ -105,6 +106,7 @@ NewCircleLoop2(depth int) NewPixelHole(dotN int) NewDotsWave(dotsN int) NewCircleMove(circleNum int) +NewCircleNoise(dotsN, colorMin, colorMax int) ``` ## Docs @@ -378,26 +380,6 @@ func main() { ![](images/oceanfish.png) -### Silk Smoke - -```go -func main() { - rand.Seed(time.Now().Unix()) - c := generativeart.NewCanva(500, 500) - c.SetBackground(common.Black) - c.SetLineWidth(1.0) - c.SetLineColor(common.MediumAquamarine) - c.SetAlpha(30) - c.SetColorSchema(common.Plasma) - c.SetIterations(4) - c.FillBackground() - c.Draw(arts.NewSilkSmoke(400, 20, 0.2, 2, 10, 30, false)) - c.ToPNG("silksmoke.png") -} -``` - -![](images/silksmoke.png) - ### Circle Loop ```go @@ -417,6 +399,24 @@ func main() { ![](images/circleloop.png) +### Circle Noise + +```go +func main() { + rand.Seed(time.Now().Unix()) + c := generativeart.NewCanva(500, 500) + c.SetBackground(common.White) + c.SetAlpha(80) + c.SetLineWidth(0.3) + c.FillBackground() + c.SetIterations(400) + c.Draw(arts.NewCircleNoise(2000, 60, 80)) + c.ToPNG("circlenoise.png") +} +``` + +![](images/circlenoise.png) + ### Julia Set ```go diff --git a/arts/circlenoise.go b/arts/circlenoise.go new file mode 100644 index 0000000..d883a4b --- /dev/null +++ b/arts/circlenoise.go @@ -0,0 +1,86 @@ +package arts + +import ( + "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" + "math" + "math/rand" +) + +type circleNoise struct { + dotsN int + colorMin, colorMax int +} + +type dot struct { + x, y float64 + prevx, prevy float64 + theta float64 + count int +} + +func NewCircleNoise(dotsN, colorMin, colorMax int) *circleNoise { + return &circleNoise{ + dotsN: dotsN, + colorMin: colorMin, + colorMax: colorMax, + } +} + +// Generative draws a circle with perlin noise. +func (cn *circleNoise) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) + ctex.SetLineWidth(2.0) + ctex.SetColor(common.Black) + radius := float64(c.Width()) * 0.8 / 2 + ctex.DrawCircle(float64(c.Width()/2), float64(c.Height()/2), radius) + ctex.Stroke() + //ctex.Clip() + + var factor = 0.008 + noise := common.NewPerlinNoise() + + dots := make([]dot, 0) + for i := 0; i < cn.dotsN; i++ { + theta := rand.Float64() * math.Pi * 2 + x, y := float64(c.Width())/2+math.Sin(theta)*radius, float64(c.Height())/2+math.Cos(theta)*radius + dots = append(dots, dot{ + theta: theta, + x: x, + y: y, + prevx: x, + prevy: y, + count: 0, + }) + } + + for j := 0; j < c.Opts().NIters(); j++ { + for i, _ := range dots { + n := noise.Noise2D(dots[i].x*factor, dots[i].y*factor) + nx, ny := math.Cos(n*math.Pi*2+float64(dots[i].count)*math.Pi)*2, math.Sin(n*math.Pi*2+float64(dots[i].count)*math.Pi)*2 + dots[i].prevx, dots[i].prevy = dots[i].x, dots[i].y + dots[i].x, dots[i].y = dots[i].x+nx, dots[i].y+ny + hsv := common.HSV{ + H: int(common.Remap(n, 0, 1, float64(cn.colorMin), float64(cn.colorMax))), + S: 100, + V: 20, + } + if common.Distance(float64(c.Width())/2, float64(c.Height())/2, dots[i].x, dots[i].y) > radius+2 { + dots[i].count += 1 + } + + if common.Distance(float64(c.Width())/2, float64(c.Height())/2, dots[i].x, dots[i].y) < radius && + common.Distance(float64(c.Width())/2, float64(c.Height())/2, dots[i].prevx, dots[i].prevy) < radius { + ctex.SetLineWidth(c.Opts().LineWidth()) + rgb := hsv.ToRGB(100, 100, 100) + rgb.A = uint8(c.Opts().Alpha()) + ctex.SetColor(rgb) + ctex.DrawLine(dots[i].prevx, dots[i].prevy, dots[i].x, dots[i].y) + ctex.Stroke() + } + + } + } + +} diff --git a/docs/doc.md b/docs/doc.md index 6cc6725..59e61cd 100644 --- a/docs/doc.md +++ b/docs/doc.md @@ -175,4 +175,14 @@ d := generativeart.NewDotsWave(300) cm := generativeart.NewCircleMove(1000) ``` -![](../images/circlemove.png) \ No newline at end of file +![](../images/circlemove.png) + +### Circle Noise + +### parameters + +- dotsN: The number of dot. +- colorMin: The minimum color. +- colorMax: The maximum color. + +![](../images/circlenoise.png) \ No newline at end of file diff --git a/example/example_circlenoise.go b/example/example_circlenoise.go new file mode 100644 index 0000000..fb036ce --- /dev/null +++ b/example/example_circlenoise.go @@ -0,0 +1,21 @@ +package main + +import ( + "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/arts" + "github.com/jdxyw/generativeart/common" + "math/rand" + "time" +) + +func main() { + rand.Seed(time.Now().Unix()) + c := generativeart.NewCanva(500, 500) + c.SetBackground(common.White) + c.SetAlpha(80) + c.SetLineWidth(0.3) + c.FillBackground() + c.SetIterations(400) + c.Draw(arts.NewCircleNoise(2000, 60, 80)) + c.ToPNG("circlenoise.png") +} diff --git a/images/circlenoise.png b/images/circlenoise.png new file mode 100644 index 0000000..3bec2c0 Binary files /dev/null and b/images/circlenoise.png differ