diff --git a/README.md b/README.md index 9e44ee2..ccc0839 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ [![Go Report Card](https://goreportcard.com/badge/github.com/jdxyw/generativeart)](https://goreportcard.com/report/github.com/jdxyw/generativeart) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/jdxyw/generativeart/master/LICENSE) - `generativeart` is a `Go` package to generate many kinds of generative art. The goal is to collect some excellent generative art (implemented in `R` or `Processing`), and rewrite them in `Go` again. I would paste the original link at the end of this README(If I remember, you can also submit a PR if you found I missed something.). Currently, it supports the following type. ## Buy me a coffee @@ -36,6 +35,7 @@ This package is still working in progress. More types would be added. Welcome an - Noise Line - Ocean Fish - Circle Loop2 +- Pixel Hole For these kinds of art, the package provides as many parameters to control the appearance. @@ -68,6 +68,7 @@ NewCircleGrid(circleNumMin, circleNumMax int) NewContourLine(lineNum int) NewNoiseLine(n int) NewCircleLoop2(depth int) +NewPixelHole(dotN int) ``` ## Docs @@ -77,37 +78,39 @@ You could find the docs in the [doc](./docs). ## Examples You could find examples for all types under [example](./example). + ## General Options ```go type Options struct { - background color.RGBA - foreground color.RGBA - lineColor color.RGBA - lineWidth float64 - colorSchema []color.RGBA - nIters int - alpha int + background color.RGBA + foreground color.RGBA + lineColor color.RGBA + lineWidth float64 + colorSchema []color.RGBA + nIters int + alpha int } ``` The `Options` is a global option for the whole `canva`. It includes those general parameters used by different kinds of types, such as `background`, `lineColor`, and `colorScheme`. For those parameters specified for different kinds of art types, they have their own `struct`. + ## Usage and example ### Junas ```go func main() { - rand.Seed(time.Now().Unix()) - c := generativeart.NewCanva(500, 500) - c.SetBackground(generativeart.Black) - c.FillBackground() - c.SetColorSchema(generativeart.DarkRed) - c.SetForeground(generativeart.LightPink) - c.Draw(generativeart.NewJanus(10, 0.2)) - c.ToPNG("janus.png") + rand.Seed(time.Now().Unix()) + c := generativeart.NewCanva(500, 500) + c.SetBackground(generativeart.Black) + c.FillBackground() + c.SetColorSchema(generativeart.DarkRed) + c.SetForeground(generativeart.LightPink) + c.Draw(generativeart.NewJanus(10, 0.2)) + c.ToPNG("janus.png") } ``` @@ -117,19 +120,19 @@ func main() { ```go func main() { - rand.Seed(time.Now().Unix()) - c := generativeart.NewCanva(500, 500) - c.SetBackground(generativeart.White) - c.FillBackground() - c.SetColorSchema([]color.RGBA{ - {0xCF, 0x2B, 0x34, 0xFF}, - {0xF0, 0x8F, 0x46, 0xFF}, - {0xF0, 0xC1, 0x29, 0xFF}, - {0x19, 0x6E, 0x94, 0xFF}, - {0x35, 0x3A, 0x57, 0xFF}, - }) - c.Draw(generativeart.NewRandomShape(150)) - c.ToPNG("randomshape.png") + rand.Seed(time.Now().Unix()) + c := generativeart.NewCanva(500, 500) + c.SetBackground(generativeart.White) + c.FillBackground() + c.SetColorSchema([]color.RGBA{ + {0xCF, 0x2B, 0x34, 0xFF}, + {0xF0, 0x8F, 0x46, 0xFF}, + {0xF0, 0xC1, 0x29, 0xFF}, + {0x19, 0x6E, 0x94, 0xFF}, + {0x35, 0x3A, 0x57, 0xFF}, + }) + c.Draw(generativeart.NewRandomShape(150)) + c.ToPNG("randomshape.png") } ``` @@ -139,20 +142,20 @@ func main() { ```go func main() { - rand.Seed(time.Now().Unix()) - colors := []color.RGBA{ - {0x11, 0x60, 0xC6, 0xFF}, - {0xFD, 0xD9, 0x00, 0xFF}, - {0xF5, 0xB4, 0xF8, 0xFF}, - {0xEF, 0x13, 0x55, 0xFF}, - {0xF4, 0x9F, 0x0A, 0xFF}, - } - c := generativeart.NewCanva(800, 800) - c.SetBackground(generativeart.White) - c.FillBackground() - c.SetColorSchema(colors) - c.Draw(generativeart.NewColorCircle2(30)) - c.ToPNG("colorcircle2.png") + rand.Seed(time.Now().Unix()) + colors := []color.RGBA{ + {0x11, 0x60, 0xC6, 0xFF}, + {0xFD, 0xD9, 0x00, 0xFF}, + {0xF5, 0xB4, 0xF8, 0xFF}, + {0xEF, 0x13, 0x55, 0xFF}, + {0xF4, 0x9F, 0x0A, 0xFF}, + } + c := generativeart.NewCanva(800, 800) + c.SetBackground(generativeart.White) + c.FillBackground() + c.SetColorSchema(colors) + c.Draw(generativeart.NewColorCircle2(30)) + c.ToPNG("colorcircle2.png") } ``` @@ -162,22 +165,22 @@ func main() { ```go func main() { - rand.Seed(time.Now().Unix()) - colors := []color.RGBA{ - {0xED, 0x34, 0x41, 0xFF}, - {0xFF, 0xD6, 0x30, 0xFF}, - {0x32, 0x9F, 0xE3, 0xFF}, - {0x15, 0x42, 0x96, 0xFF}, - {0x00, 0x00, 0x00, 0xFF}, - {0xFF, 0xFF, 0xFF, 0xFF}, - } - c := generativeart.NewCanva(500, 500) - c.SetBackground(color.RGBA{0xDF, 0xEB, 0xF5, 0xFF}) - c.FillBackground() - c.SetColorSchema(colors) - c.SetLineWidth(2.0) - c.Draw(generativeart.NewCircleGrid(4, 6)) - c.ToPNG("circlegrid.png") + rand.Seed(time.Now().Unix()) + colors := []color.RGBA{ + {0xED, 0x34, 0x41, 0xFF}, + {0xFF, 0xD6, 0x30, 0xFF}, + {0x32, 0x9F, 0xE3, 0xFF}, + {0x15, 0x42, 0x96, 0xFF}, + {0x00, 0x00, 0x00, 0xFF}, + {0xFF, 0xFF, 0xFF, 0xFF}, + } + c := generativeart.NewCanva(500, 500) + c.SetBackground(color.RGBA{0xDF, 0xEB, 0xF5, 0xFF}) + c.FillBackground() + c.SetColorSchema(colors) + c.SetLineWidth(2.0) + c.Draw(generativeart.NewCircleGrid(4, 6)) + c.ToPNG("circlegrid.png") } ``` @@ -187,40 +190,64 @@ func main() { ```go func main() { - rand.Seed(time.Now().Unix()) - colors := []color.RGBA{ - {0xF9, 0xC8, 0x0E, 0xFF}, - {0xF8, 0x66, 0x24, 0xFF}, - {0xEA, 0x35, 0x46, 0xFF}, - {0x66, 0x2E, 0x9B, 0xFF}, - {0x43, 0xBC, 0xCD, 0xFF}, - } - c := generativeart.NewCanva(500, 500) - c.SetBackground(color.RGBA{8, 10, 20, 255}) - c.FillBackground() - c.SetColorSchema(colors) - c.Draw(generativeart.NewCircleLoop2(7)) - c.ToPNG("colorloop2.png") + rand.Seed(time.Now().Unix()) + colors := []color.RGBA{ + {0xF9, 0xC8, 0x0E, 0xFF}, + {0xF8, 0x66, 0x24, 0xFF}, + {0xEA, 0x35, 0x46, 0xFF}, + {0x66, 0x2E, 0x9B, 0xFF}, + {0x43, 0xBC, 0xCD, 0xFF}, + } + c := generativeart.NewCanva(500, 500) + c.SetBackground(color.RGBA{8, 10, 20, 255}) + c.FillBackground() + c.SetColorSchema(colors) + c.Draw(generativeart.NewCircleLoop2(7)) + c.ToPNG("colorloop2.png") } ``` ![](images/colorloop2.png) +## Pixel Hole + +```go +func main() { + rand.Seed(time.Now().Unix()) + colors := []color.RGBA{ + {0xF9, 0xC8, 0x0E, 0xFF}, + {0xF8, 0x66, 0x24, 0xFF}, + {0xEA, 0x35, 0x46, 0xFF}, + {0x66, 0x2E, 0x9B, 0xFF}, + {0x43, 0xBC, 0xCD, 0xFF}, + } + c := generativeart.NewCanva(800, 800) + c.SetBackground(common.Black) + c.FillBackground() + c.SetColorSchema(colors) + c.SetIterations(1200) + c.Draw(generativeart.NewPixelHole(60)) + c.ToPNG("pixelhole.png") +} +``` + +![](images/pixelhole.png) + ### Silk Smoke ```go func main() { - rand.Seed(time.Now().Unix()) - c := generativeart.NewCanva(500, 500) - c.SetBackground(generativeart.Black) - c.SetLineWidth(1.0) - c.SetLineColor(generativeart.MediumAquamarine) - c.SetAlpha(30) - c.SetColorSchema(generativeart.Plasma) - c.SetIterations(4) - c.FillBackground() - c.Draw(generativeart.NewSilkSmoke(400, 20, 0.2, 2, 10, 30, false)) - c.ToPNG("silksmoke.png") + rand.Seed(time.Now().Unix()) + c := generativeart.NewCanva(500, 500) + c.SetBackground(generativeart.Black) + c.SetLineWidth(1.0) + c.SetLineColor(generativeart.MediumAquamarine) + c.SetAlpha(30) + c.SetColorSchema(generativeart.Plasma) + c.SetIterations(4) + c.FillBackground() + c.Draw(generativeart.NewSilkSmoke(400, 20, 0.2, 2, 10, 30, false)) + c.ToPNG("silksmoke.png") } ``` @@ -230,20 +257,20 @@ func main() { ```go func main() { - rand.Seed(time.Now().Unix()) - colors := []color.RGBA{ - {0x58, 0x18, 0x45, 0xFF}, - {0x90, 0x0C, 0x3F, 0xFF}, - {0xC7, 0x00, 0x39, 0xFF}, - {0xFF, 0x57, 0x33, 0xFF}, - {0xFF, 0xC3, 0x0F, 0xFF}, - } - c := generativeart.NewCanva(1600, 1600) - c.SetBackground(color.RGBA{0x1a, 0x06, 0x33, 0xFF}) - c.FillBackground() - c.SetColorSchema(colors) - c.Draw(generativeart.NewContourLine(500)) - c.ToPNG("contourline.png") + rand.Seed(time.Now().Unix()) + colors := []color.RGBA{ + {0x58, 0x18, 0x45, 0xFF}, + {0x90, 0x0C, 0x3F, 0xFF}, + {0xC7, 0x00, 0x39, 0xFF}, + {0xFF, 0x57, 0x33, 0xFF}, + {0xFF, 0xC3, 0x0F, 0xFF}, + } + c := generativeart.NewCanva(1600, 1600) + c.SetBackground(color.RGBA{0x1a, 0x06, 0x33, 0xFF}) + c.FillBackground() + c.SetColorSchema(colors) + c.Draw(generativeart.NewContourLine(500)) + c.ToPNG("contourline.png") } ``` @@ -253,20 +280,20 @@ func main() { ```go func main() { - rand.Seed(time.Now().Unix()) - colors := []color.RGBA{ - {0x06, 0x7B, 0xC2, 0xFF}, - {0x84, 0xBC, 0xDA, 0xFF}, - {0xEC, 0xC3, 0x0B, 0xFF}, - {0xF3, 0x77, 0x48, 0xFF}, - {0xD5, 0x60, 0x62, 0xFF}, - } - c := generativeart.NewCanva(1000, 1000) - c.SetBackground(color.RGBA{0xF0, 0xFE, 0xFF, 0xFF}) - c.FillBackground() - c.SetColorSchema(colors) - c.Draw(generativeart.NewNoiseLine(1000)) - c.ToPNG("noiseline.png") + rand.Seed(time.Now().Unix()) + colors := []color.RGBA{ + {0x06, 0x7B, 0xC2, 0xFF}, + {0x84, 0xBC, 0xDA, 0xFF}, + {0xEC, 0xC3, 0x0B, 0xFF}, + {0xF3, 0x77, 0x48, 0xFF}, + {0xD5, 0x60, 0x62, 0xFF}, + } + c := generativeart.NewCanva(1000, 1000) + c.SetBackground(color.RGBA{0xF0, 0xFE, 0xFF, 0xFF}) + c.FillBackground() + c.SetColorSchema(colors) + c.Draw(generativeart.NewNoiseLine(1000)) + c.ToPNG("noiseline.png") } ``` @@ -276,15 +303,15 @@ func main() { ```go func main() { - rand.Seed(time.Now().Unix()) - c := generativeart.NewCanva(2080, 2080) - c.SetBackground(color.RGBA{230, 230, 230, 255}) - c.SetLineWidth(10) - c.SetIterations(4000) - c.SetColorSchema(generativeart.Plasma) - c.FillBackground() - c.Draw(generativeart.NewDotLine(100, 20, 50, false)) - c.ToPNG("dotline.png") + rand.Seed(time.Now().Unix()) + c := generativeart.NewCanva(2080, 2080) + c.SetBackground(color.RGBA{230, 230, 230, 255}) + c.SetLineWidth(10) + c.SetIterations(4000) + c.SetColorSchema(generativeart.Plasma) + c.FillBackground() + c.Draw(generativeart.NewDotLine(100, 20, 50, false)) + c.ToPNG("dotline.png") } ``` @@ -294,18 +321,18 @@ func main() { ```go func main() { - rand.Seed(time.Now().Unix()) - colors := []color.RGBA{ - {0xCF, 0x2B, 0x34, 0xFF}, - {0xF0, 0x8F, 0x46, 0xFF}, - {0xF0, 0xC1, 0x29, 0xFF}, - {0x19, 0x6E, 0x94, 0xFF}, - {0x35, 0x3A, 0x57, 0xFF}, - } - c := generativeart.NewCanva(500, 500) - c.SetColorSchema(colors) - c.Draw(generativeart.NewOceanFish(100, 8)) - c.ToPNG("oceanfish.png") + rand.Seed(time.Now().Unix()) + colors := []color.RGBA{ + {0xCF, 0x2B, 0x34, 0xFF}, + {0xF0, 0x8F, 0x46, 0xFF}, + {0xF0, 0xC1, 0x29, 0xFF}, + {0x19, 0x6E, 0x94, 0xFF}, + {0x35, 0x3A, 0x57, 0xFF}, + } + c := generativeart.NewCanva(500, 500) + c.SetColorSchema(colors) + c.Draw(generativeart.NewOceanFish(100, 8)) + c.ToPNG("oceanfish.png") } ``` @@ -315,40 +342,39 @@ func main() { ```go func main() { - rand.Seed(time.Now().Unix()) - c := generativeart.NewCanva(500, 500) - c.SetBackground(generativeart.Black) - c.SetLineWidth(1) - c.SetLineColor(generativeart.Orange) - c.SetAlpha(30) - c.SetIterations(1000) - c.FillBackground() - c.Draw(generativeart.NewCircleLoop(100)) - c.ToPNG("circleloop.png") + rand.Seed(time.Now().Unix()) + c := generativeart.NewCanva(500, 500) + c.SetBackground(generativeart.Black) + c.SetLineWidth(1) + c.SetLineColor(generativeart.Orange) + c.SetAlpha(30) + c.SetIterations(1000) + c.FillBackground() + c.Draw(generativeart.NewCircleLoop(100)) + c.ToPNG("circleloop.png") } ``` ![](images/circleloop.png) - ### Julia Set ```go func julia1(z complex128) complex128 { - c := complex(-0.1, 0.651) - z = z*z + c + c := complex(-0.1, 0.651) + z = z*z + c - return z + return z } func main() { - rand.Seed(time.Now().Unix()) - c := generativeart.NewCanva(500, 500) - c.SetIterations(800) - c.SetColorSchema(generativeart.Viridis) - c.FillBackground() - c.Draw(generativeart.NewJulia(julia1, 40, 1.5, 1.5)) - c.ToPNG("julia.png") + rand.Seed(time.Now().Unix()) + c := generativeart.NewCanva(500, 500) + c.SetIterations(800) + c.SetColorSchema(generativeart.Viridis) + c.FillBackground() + c.Draw(generativeart.NewJulia(julia1, 40, 1.5, 1.5)) + c.ToPNG("julia.png") } ``` @@ -358,11 +384,11 @@ func main() { ```go func main() { - rand.Seed(time.Now().Unix()) - c := generativeart.NewCanva(600, 600) - c.SetAlpha(10) - c.Draw(generativeart.NewSilkSky(15, 5)) - c.ToPNG("silksky.png") + rand.Seed(time.Now().Unix()) + c := generativeart.NewCanva(600, 600) + c.SetAlpha(10) + c.Draw(generativeart.NewSilkSky(15, 5)) + c.ToPNG("silksky.png") } ``` @@ -372,14 +398,14 @@ func main() { ```go func main() { - rand.Seed(time.Now().Unix()) - c := generativeart.NewCanva(600, 600) - c.SetBackground(generativeart.Azure) - c.SetLineWidth(3) - c.SetLineColor(generativeart.Orange) - c.FillBackground() - c.Draw(generativeart.NewMaze(20)) - c.ToPNG("maze.png") + rand.Seed(time.Now().Unix()) + c := generativeart.NewCanva(600, 600) + c.SetBackground(generativeart.Azure) + c.SetLineWidth(3) + c.SetLineColor(generativeart.Orange) + c.FillBackground() + c.Draw(generativeart.NewMaze(20)) + c.ToPNG("maze.png") } ``` @@ -389,21 +415,21 @@ func main() { ```go func main() { - rand.Seed(time.Now().Unix()) - c := generativeart.NewCanva(500, 500) - c.SetBackground(generativeart.MistyRose) - c.SetLineWidth(1.0) - c.SetLineColor(color.RGBA{ - R: 122, - G: 122, - B: 122, - A: 30, - }) - c.SetColorSchema(generativeart.Plasma) - c.SetIterations(4) - c.FillBackground() - c.Draw(generativeart.NewRandCicle(30, 80, 0.2, 2, 10, 30, true)) - c.ToPNG("randcircle.png") + rand.Seed(time.Now().Unix()) + c := generativeart.NewCanva(500, 500) + c.SetBackground(generativeart.MistyRose) + c.SetLineWidth(1.0) + c.SetLineColor(color.RGBA{ + R: 122, + G: 122, + B: 122, + A: 30, + }) + c.SetColorSchema(generativeart.Plasma) + c.SetIterations(4) + c.FillBackground() + c.Draw(generativeart.NewRandCicle(30, 80, 0.2, 2, 10, 30, true)) + c.ToPNG("randcircle.png") } ``` @@ -417,19 +443,20 @@ func main() { Thanks for the following sites and repos, I got lots of ideas, inspiration, code, and tricks from them. The list would be very long; sorry for forgetting some of them. -- https://inconvergent.net/ -- https://fronkonstin.com/ -- https://github.com/aschinchon/cyclic-cellular-automata -- https://github.com/armdz/ProcessingSketchs -- https://github.com/Mr-Slesser/Generative-Art-And-Fractals -- https://github.com/cdr6934/Generative-Processing-Experiments -- 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/ -- https://editor.p5js.org/kenekk1/sketches/O44Dln5oo -- https://openprocessing.org/sketch/1071233 -- https://twitter.com/okazz_ -- https://openprocessing.org/sketch/738638 -- https://openprocessing.org/sketch/1102157 -- https://openprocessing.org/sketch/1071233 \ No newline at end of file +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- diff --git a/common/calculation.go b/common/calculation.go index 3153364..b69507b 100644 --- a/common/calculation.go +++ b/common/calculation.go @@ -1,6 +1,9 @@ package common -import "math" +import ( + "image/color" + "math" +) // Constrain returns a value between a minimum and maximum value. func Constrain(val, low, high float64) float64 { @@ -17,3 +20,13 @@ func Remap(n, start1, stop1, start2, stop2 float64) float64 { return Constrain(newval, stop2, start2) } } + +// LerpColor blends two colors to find a third color somewhere between them. +func LerpColor(c1, c2 color.RGBA, ratio float64) color.RGBA { + r := uint8(float64(c1.R)*ratio + float64(c2.R)*(1-ratio)) + g := uint8(float64(c1.G)*ratio + float64(c2.G)*(1-ratio)) + b := uint8(float64(c1.B)*ratio + float64(c2.B)*(1-ratio)) + a := uint8(float64(c1.A)*ratio + float64(c2.A)*(1-ratio)) + + return color.RGBA{r, g, b, a} +} diff --git a/color.go b/common/color.go similarity index 99% rename from color.go rename to common/color.go index 75c6994..ccb955e 100644 --- a/color.go +++ b/common/color.go @@ -1,4 +1,4 @@ -package generativeart +package common import "image/color" diff --git a/docs/doc.md b/docs/doc.md index 1371d18..73decb5 100644 --- a/docs/doc.md +++ b/docs/doc.md @@ -136,4 +136,18 @@ o := generativeart.NewOceanFish(100, 8) cl := generativeart.NewCircleLoop2(7) ``` -![](../images/colorloop2.png) \ No newline at end of file +![](../images/colorloop2.png) + +## Pixel Hole + +`Pixel Hole` draws a hole with colored dots. + +### parameters + +- dotN: The number of point in each iteration. + +```go +ph := generativeart.NewPixelHole(60) +``` + +![](../images/pixelhole.png) \ No newline at end of file diff --git a/example/example_circleline.go b/example/example_circleline.go index 40065ad..828b412 100644 --- a/example/example_circleline.go +++ b/example/example_circleline.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "math/rand" "time" ) @@ -9,9 +10,9 @@ import ( func main() { rand.Seed(time.Now().Unix()) c := generativeart.NewCanva(600, 600) - c.SetBackground(generativeart.Tan) + c.SetBackground(common.Tan) c.SetLineWidth(1.0) - c.SetLineColor(generativeart.LightPink) + c.SetLineColor(common.LightPink) c.FillBackground() c.Draw(generativeart.NewCircleLine(0.02, 600, 1.5, 2, 2)) c.ToPNG("circleline.png") diff --git a/example/example_circleloop.go b/example/example_circleloop.go index c9ea2ca..fed6e38 100644 --- a/example/example_circleloop.go +++ b/example/example_circleloop.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "math/rand" "time" ) @@ -9,9 +10,9 @@ import ( func main() { rand.Seed(time.Now().Unix()) c := generativeart.NewCanva(500, 500) - c.SetBackground(generativeart.Black) + c.SetBackground(common.Black) c.SetLineWidth(1) - c.SetLineColor(generativeart.Orange) + c.SetLineColor(common.Orange) c.SetAlpha(30) c.SetIterations(1000) c.FillBackground() diff --git a/example/example_colorcircle.go b/example/example_colorcircle.go index b44f458..0737bd1 100644 --- a/example/example_colorcircle.go +++ b/example/example_colorcircle.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "image/color" "math/rand" "time" @@ -20,7 +21,7 @@ func main() { {0xFF, 0xFF, 0xFF, 0xFF}, } c := generativeart.NewCanva(1000, 1000) - c.SetBackground(generativeart.White) + c.SetBackground(common.White) c.FillBackground() c.SetColorSchema(colors) c.Draw(generativeart.NewColorCircle(500)) diff --git a/example/example_colorcircle2.go b/example/example_colorcircle2.go index bd778f7..d0a0f5e 100644 --- a/example/example_colorcircle2.go +++ b/example/example_colorcircle2.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "image/color" "math/rand" "time" @@ -17,7 +18,7 @@ func main() { {0xF4, 0x9F, 0x0A, 0xFF}, } c := generativeart.NewCanva(800, 800) - c.SetBackground(generativeart.White) + c.SetBackground(common.White) c.FillBackground() c.SetColorSchema(colors) c.Draw(generativeart.NewColorCircle2(30)) diff --git a/example/example_dotline.go b/example/example_dotline.go index 91f907f..071dc35 100644 --- a/example/example_dotline.go +++ b/example/example_dotline.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "image/color" "math/rand" "time" @@ -13,7 +14,7 @@ func main() { c.SetBackground(color.RGBA{230, 230, 230, 255}) c.SetLineWidth(10) c.SetIterations(15000) - c.SetColorSchema(generativeart.Plasma) + c.SetColorSchema(common.Plasma) c.FillBackground() c.Draw(generativeart.NewDotLine(100, 20, 50, false)) c.ToPNG("dotline.png") diff --git a/example/example_gridsquare.go b/example/example_gridsquare.go index 2b41fd0..a92f97e 100644 --- a/example/example_gridsquare.go +++ b/example/example_gridsquare.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "math/rand" "time" ) @@ -9,8 +10,8 @@ import ( func main() { rand.Seed(time.Now().Unix()) c := generativeart.NewCanva(600, 600) - c.SetBackground(generativeart.DarkPink[rand.Intn(5)]) - c.SetColorSchema(generativeart.DarkPink) + c.SetBackground(common.DarkPink[rand.Intn(5)]) + c.SetColorSchema(common.DarkPink) c.Draw(generativeart.NewGirdSquares(24, 10, 0.2)) c.ToPNG("gsquare.png") } diff --git a/example/example_janus.go b/example/example_janus.go index 71b57b4..ba70c6f 100644 --- a/example/example_janus.go +++ b/example/example_janus.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "math/rand" "time" ) @@ -9,10 +10,10 @@ import ( func main() { rand.Seed(time.Now().Unix()) c := generativeart.NewCanva(500, 500) - c.SetBackground(generativeart.Black) + c.SetBackground(common.Black) c.FillBackground() - c.SetColorSchema(generativeart.DarkRed) - c.SetForeground(generativeart.LightPink) + c.SetColorSchema(common.DarkRed) + c.SetForeground(common.LightPink) c.Draw(generativeart.NewJanus(10, 0.2)) c.ToPNG("janus.png") } diff --git a/example/example_julia.go b/example/example_julia.go index 7454e7f..89828a3 100644 --- a/example/example_julia.go +++ b/example/example_julia.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "math/rand" "time" ) @@ -18,7 +19,7 @@ func main() { rand.Seed(time.Now().Unix()) c := generativeart.NewCanva(500, 500) c.SetIterations(800) - c.SetColorSchema(generativeart.Viridis) + c.SetColorSchema(common.Viridis) c.FillBackground() c.Draw(generativeart.NewJulia(julia1, 40, 1.5, 1.5)) c.ToPNG("julia.png") diff --git a/example/example_maze.go b/example/example_maze.go index 2e11b74..b55f51f 100644 --- a/example/example_maze.go +++ b/example/example_maze.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "math/rand" "time" ) @@ -9,9 +10,9 @@ import ( func main() { rand.Seed(time.Now().Unix()) c := generativeart.NewCanva(600, 600) - c.SetBackground(generativeart.Azure) + c.SetBackground(common.Azure) c.SetLineWidth(3) - c.SetLineColor(generativeart.Orange) + c.SetLineColor(common.Orange) c.FillBackground() c.Draw(generativeart.NewMaze(20)) c.ToPNG("maze.png") diff --git a/example/example_pixelhole.go b/example/example_pixelhole.go new file mode 100644 index 0000000..c6ee556 --- /dev/null +++ b/example/example_pixelhole.go @@ -0,0 +1,28 @@ +package main + +import ( + "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" + "image/color" + "math/rand" + "time" +) + +func main() { + rand.Seed(time.Now().Unix()) + colors := []color.RGBA{ + {0xF9, 0xC8, 0x0E, 0xFF}, + {0xF8, 0x66, 0x24, 0xFF}, + {0xEA, 0x35, 0x46, 0xFF}, + {0x66, 0x2E, 0x9B, 0xFF}, + {0x43, 0xBC, 0xCD, 0xFF}, + } + c := generativeart.NewCanva(800, 800) + c.SetBackground(common.Black) + c.FillBackground() + c.SetColorSchema(colors) + c.SetIterations(1200) + c.Draw(generativeart.NewPixelHole(60)) + c.ToPNG("pixelhole.png") + +} diff --git a/example/example_pointribbon.go b/example/example_pointribbon.go index 3964ec6..bbb85e8 100644 --- a/example/example_pointribbon.go +++ b/example/example_pointribbon.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "math/rand" "time" ) @@ -9,7 +10,7 @@ import ( func main() { rand.Seed(time.Now().Unix()) c := generativeart.NewCanva(500, 500) - c.SetBackground(generativeart.Lavender) + c.SetBackground(common.Lavender) c.SetLineWidth(2) c.SetIterations(150000) c.FillBackground() diff --git a/example/example_randcircle.go b/example/example_randcircle.go index 45b4217..58bb826 100644 --- a/example/example_randcircle.go +++ b/example/example_randcircle.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "image/color" "math/rand" "time" @@ -10,7 +11,7 @@ import ( func main() { rand.Seed(time.Now().Unix()) c := generativeart.NewCanva(500, 500) - c.SetBackground(generativeart.MistyRose) + c.SetBackground(common.MistyRose) c.SetLineWidth(1.0) c.SetLineColor(color.RGBA{ R: 122, @@ -18,7 +19,7 @@ func main() { B: 122, A: 30, }) - c.SetColorSchema(generativeart.Plasma) + c.SetColorSchema(common.Plasma) c.SetIterations(4) c.FillBackground() c.Draw(generativeart.NewRandCicle(30, 80, 0.2, 2, 10, 30, true)) diff --git a/example/example_randomshape.go b/example/example_randomshape.go index df81d2e..0a0a5d5 100644 --- a/example/example_randomshape.go +++ b/example/example_randomshape.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "image/color" "math/rand" "time" @@ -10,7 +11,7 @@ import ( func main() { rand.Seed(time.Now().Unix()) c := generativeart.NewCanva(500, 500) - c.SetBackground(generativeart.White) + c.SetBackground(common.White) c.FillBackground() c.SetColorSchema([]color.RGBA{ {0xCF, 0x2B, 0x34, 0xFF}, diff --git a/example/example_silksmoke.go b/example/example_silksmoke.go index 13200c9..14b4f76 100644 --- a/example/example_silksmoke.go +++ b/example/example_silksmoke.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "math/rand" "time" ) @@ -9,11 +10,11 @@ import ( func main() { rand.Seed(time.Now().Unix()) c := generativeart.NewCanva(500, 500) - c.SetBackground(generativeart.Black) + c.SetBackground(common.Black) c.SetLineWidth(1.0) - c.SetLineColor(generativeart.MediumAquamarine) + c.SetLineColor(common.MediumAquamarine) c.SetAlpha(30) - c.SetColorSchema(generativeart.Plasma) + c.SetColorSchema(common.Plasma) c.SetIterations(4) c.FillBackground() c.Draw(generativeart.NewSilkSmoke(400, 20, 0.2, 2, 10, 30, false)) diff --git a/example/example_spiralsquare.go b/example/example_spiralsquare.go index 44f9e4d..182c15e 100644 --- a/example/example_spiralsquare.go +++ b/example/example_spiralsquare.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "math/rand" "time" ) @@ -9,11 +10,11 @@ import ( func main() { rand.Seed(time.Now().Unix()) c := generativeart.NewCanva(500, 500) - c.SetBackground(generativeart.MistyRose) + c.SetBackground(common.MistyRose) c.SetLineWidth(10) - c.SetLineColor(generativeart.Orange) - c.SetColorSchema(generativeart.Plasma) - c.SetForeground(generativeart.Tomato) + c.SetLineColor(common.Orange) + c.SetColorSchema(common.Plasma) + c.SetForeground(common.Tomato) c.FillBackground() c.Draw(generativeart.NewSpiralSquare(40, 400, 0.05, true)) c.ToPNG("spiralsquare.png") diff --git a/example/example_swirl.go b/example/example_swirl.go index 02cbc69..f5a09ba 100644 --- a/example/example_swirl.go +++ b/example/example_swirl.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" "image/color" "math/rand" "time" @@ -10,7 +11,7 @@ import ( func main() { rand.Seed(time.Now().Unix()) c := generativeart.NewCanva(1600, 1600) - c.SetBackground(generativeart.Azure) + c.SetBackground(common.Azure) c.FillBackground() c.SetForeground(color.RGBA{113, 3, 0, 140}) c.SetIterations(4000000) diff --git a/generativeart.go b/generativeart.go index 4074a6d..85f47c7 100644 --- a/generativeart.go +++ b/generativeart.go @@ -1,6 +1,7 @@ package generativeart import ( + "github.com/jdxyw/generativeart/common" "image" "image/color" "image/draw" @@ -37,11 +38,11 @@ func NewCanva(h, w int) *canva { img: image.NewRGBA(image.Rect(0, 0, h, w)), // Set some defaults value opts: Options{ - background: Azure, - foreground: MistyRose, - lineColor: Tomato, + background: common.Azure, + foreground: common.MistyRose, + lineColor: common.Tomato, lineWidth: 3, - colorSchema: Plasma, + colorSchema: common.Plasma, nIters: 20, alpha: 255, }, diff --git a/images/pixelhole.png b/images/pixelhole.png new file mode 100644 index 0000000..f6de036 Binary files /dev/null and b/images/pixelhole.png differ diff --git a/noiseline.go b/noiseline.go index ac1b1e8..c628acb 100644 --- a/noiseline.go +++ b/noiseline.go @@ -23,7 +23,7 @@ func (nl *noiseLine) Generative(c *canva) { ctex := gg.NewContextForRGBA(c.img) noise := common.NewPerlinNoise() - ctex.SetColor(Black) + ctex.SetColor(common.Black) for i := 0; i < 80; i++ { x := rand.Float64() * float64(c.width) y := rand.Float64() * float64(c.height) diff --git a/pixelhole.go b/pixelhole.go new file mode 100644 index 0000000..2761b03 --- /dev/null +++ b/pixelhole.go @@ -0,0 +1,55 @@ +package generativeart + +import ( + "github.com/fogleman/gg" + "github.com/jdxyw/generativeart/common" + "math" + "math/rand" +) + +type pixelHole struct { + dotN int + noise *common.PerlinNoise +} + +// NewPixelHole returns a pixelHole object. +func NewPixelHole(dotN int) *pixelHole { + return &pixelHole{ + dotN: dotN, + noise: common.NewPerlinNoise(), + } +} + +// Generative draws a pixel hole images. +func (p *pixelHole) Generative(c *canva) { + ctex := gg.NewContextForRGBA(c.img) + //ctex.Translate(float64(c.width)/2, float64(c.height)/2) + for i := 0.0; i < float64(c.opts.nIters); i += 1.0 { + ctex.Push() + ctex.Translate(float64(c.width)/2, float64(c.height)/2) + p.draw(ctex, c, i) + ctex.Pop() + } +} + +func (p *pixelHole) draw(ctex *gg.Context, c *canva, frameCount float64) { + ctex.SetLineWidth(2.0) + c1 := int(frameCount/100.0) % len(c.opts.colorSchema) + c2 := (int(frameCount/100.0) + 1) % len(c.opts.colorSchema) + ratio := frameCount/100 - math.Floor(frameCount/100) + cl := common.LerpColor(c.opts.colorSchema[c1], c.opts.colorSchema[c2], ratio) + for i := 0.0; i < float64(p.dotN); i += 1.0 { + ctex.Push() + ctex.SetColor(cl) + ctex.Rotate(frameCount/(50+10*math.Log(frameCount+1)) + i/20) + dd := frameCount/(5+i) + frameCount/5 + math.Sin(i)*50 + ctex.Translate(common.RandomRangeFloat64(dd/2, dd), 0) + x := p.noise.Noise2D(frameCount/50+i/50, 5000)*float64(c.width)/10 + rand.Float64()*float64(c.width)/20 + y := p.noise.Noise2D(frameCount/50+i/50, 10000)*float64(c.height)/10 + rand.Float64()*float64(c.height)/20 + + rr := common.RandomRangeFloat64(1.0, 6-math.Log(frameCount+1)/10) + ctex.DrawEllipse(x, y, rr, rr) + ctex.Fill() + ctex.Pop() + } +}