From c25daba2eda4ea95cfb8ef3a3ddbf1c7ee1483d0 Mon Sep 17 00:00:00 2001 From: Yongwei Xing Date: Tue, 9 Mar 2021 13:10:53 +0800 Subject: [PATCH] move the util file to the common folder; add contour line --- circlegrid.go | 15 +++++---- circleline.go | 3 +- colorcircle.go | 19 +++++------ colorcircle2.go | 11 ++++--- utils.go => common/utils.go | 2 +- utils_test.go => common/utils_test.go | 2 +- contourline.go | 46 +++++++++++++++++++++++++++ dotLine.go | 5 +-- example/example_contourline.go | 25 +++++++++++++++ go.mod | 1 + go.sum | 2 ++ janus.go | 5 +-- randcircle.go | 3 +- randomshape.go | 13 ++++---- silksky.go | 5 +-- silksmoke.go | 3 +- swirl.go | 3 +- 17 files changed, 124 insertions(+), 39 deletions(-) rename utils.go => common/utils.go (99%) rename utils_test.go => common/utils_test.go (96%) create mode 100644 contourline.go create mode 100644 example/example_contourline.go diff --git a/circlegrid.go b/circlegrid.go index 27ca295..38e0c4a 100644 --- a/circlegrid.go +++ b/circlegrid.go @@ -2,6 +2,7 @@ package generativeart import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart/common" "image/color" "math" "math/rand" @@ -27,7 +28,7 @@ func (cg *circleGrid) Generative(c *canva) { ctex.Scale(0.9, 0.9) ctex.Translate(-float64(c.width)/2, -float64(c.height)/2) - seg := RandomRangeInt(cg.circleNumMin, cg.circleNumMax) + seg := common.RandomRangeInt(cg.circleNumMin, cg.circleNumMax) w := float64(c.width) / float64(seg) for i := 0; i < seg; i++ { @@ -35,9 +36,9 @@ func (cg *circleGrid) Generative(c *canva) { x := float64(i)*w + w/2 y := float64(j)*w + w/2 ctex.SetColor(c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))]) - ctex.DrawCircle(x, y, w/2*RandomRangeFloat64(0.1, 0.5)) + ctex.DrawCircle(x, y, w/2*common.RandomRangeFloat64(0.1, 0.5)) ctex.Fill() - cg.draw(ctex, c, x, y, w/2*RandomRangeFloat64(0.6, 0.95)) + cg.draw(ctex, c, x, y, w/2*common.RandomRangeFloat64(0.6, 0.95)) } } } @@ -56,7 +57,7 @@ func (cg *circleGrid) draw(ctex *gg.Context, c *canva, x, y, r float64) { ctex.DrawCircle(0, 0, r) ctex.Stroke() case 1: - n := RandomRangeInt(1, 4) * 2 + n := common.RandomRangeInt(1, 4) * 2 ctex.DrawCircle(0, 0, r) ctex.Stroke() for i := 0; i < n; i++ { @@ -65,8 +66,8 @@ func (cg *circleGrid) draw(ctex *gg.Context, c *canva, x, y, r float64) { ctex.Fill() } case 2: - n := RandomRangeInt(8, 20) - theta := math.Pi * 0.5 * float64(RandomRangeInt(1, 5)) + n := common.RandomRangeInt(8, 20) + theta := math.Pi * 0.5 * float64(common.RandomRangeInt(1, 5)) for i := 0; i < n; i++ { d := float64(i) / float64(n) if d > r*0.1 { @@ -77,7 +78,7 @@ func (cg *circleGrid) draw(ctex *gg.Context, c *canva, x, y, r float64) { ctex.Fill() } case 3: - n := RandomRangeInt(5, 20) + n := common.RandomRangeInt(5, 20) for i := 0; i < n; i++ { ctex.Rotate(math.Pi * 2 / float64(n)) ctex.DrawLine(r/2, 0, (r*2/3)-(r*0.05), 0) diff --git a/circleline.go b/circleline.go index 88ffc10..c991da5 100644 --- a/circleline.go +++ b/circleline.go @@ -2,6 +2,7 @@ package generativeart import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart/common" "math" "math/rand" ) @@ -37,7 +38,7 @@ func (cl *circleLine) Generative(c *canva) { for theta := -math.Pi; theta <= math.Pi; theta += cl.step { x := cl.radius * math.Cos(theta) y := cl.radius * math.Sin(theta) - xi, yi := ConvertCartesianToPixel(x, y, cl.xaixs, cl.yaixs, c.width, c.height) + xi, yi := common.ConvertCartesianToPixel(x, y, cl.xaixs, cl.yaixs, c.width, c.height) points = append(points, point{ x: float64(xi), y: float64(yi), diff --git a/colorcircle.go b/colorcircle.go index 742d09d..207ff02 100644 --- a/colorcircle.go +++ b/colorcircle.go @@ -2,6 +2,7 @@ package generativeart import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart/common" "math" "math/rand" ) @@ -22,9 +23,9 @@ func (cc *colorCircle) Generative(c *canva) { for i := 0; i < cc.circleNum; i++ { rnd := rand.Intn(3) - x := RandomRangeFloat64(-0.1, 1.1) * float64(c.width) - y := RandomRangeFloat64(-0.1, 1.1) * float64(c.height) - s := RandomRangeFloat64(0, RandomRangeFloat64(0, float64(c.width/2))) + 10 + x := common.RandomRangeFloat64(-0.1, 1.1) * float64(c.width) + y := common.RandomRangeFloat64(-0.1, 1.1) * float64(c.height) + s := common.RandomRangeFloat64(0, common.RandomRangeFloat64(0, float64(c.width/2))) + 10 if rnd == 2 { rnd = rand.Intn(3) } @@ -32,9 +33,9 @@ func (cc *colorCircle) Generative(c *canva) { case 0: cc.drawCircleV1(ctex, c, x, y, s) case 1: - ctex.SetLineWidth(RandomRangeFloat64(0, 1)) + ctex.SetLineWidth(common.RandomRangeFloat64(0, 1)) ctex.SetColor(c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))]) - ctex.DrawCircle(x, y, RandomRangeFloat64(0, s)/2) + ctex.DrawCircle(x, y, common.RandomRangeFloat64(0, s)/2) ctex.Stroke() case 2: cc.drawCircleV2(ctex, c, x, y, s) @@ -43,8 +44,8 @@ func (cc *colorCircle) Generative(c *canva) { } func (cc *colorCircle) drawCircleV1(ctex *gg.Context, c *canva, x, y, s float64) { - n := RandomRangeInt(4, 30) - cs := RandomRangeFloat64(2, 8) + n := common.RandomRangeInt(4, 30) + cs := common.RandomRangeFloat64(2, 8) ctex.SetColor(c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))]) ctex.Push() ctex.Translate(x, y) @@ -58,7 +59,7 @@ func (cc *colorCircle) drawCircleV1(ctex *gg.Context, c *canva, x, y, s float64) func (cc *colorCircle) drawCircleV2(ctex *gg.Context, c *canva, x, y, s float64) { cl := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))] ctex.SetLineWidth(1.0) - sx := s * RandomRangeFloat64(0.1, 0.55) + sx := s * common.RandomRangeFloat64(0.1, 0.55) for j := 0.0001; j < sx; j++ { dd := s + j*2.0 alpha := int(255 * sx / j) @@ -75,7 +76,7 @@ func (cc *colorCircle) drawCircleV2(ctex *gg.Context, c *canva, x, y, s float64) ctex.SetColor(cl) for i := 0; i < 200; i++ { - theta := RandomRangeFloat64(0, math.Pi*2) + theta := common.RandomRangeFloat64(0, math.Pi*2) xx := x + dd*0.3*math.Cos(theta) yy := y + dd*0.3*math.Sin(theta) //ctex.DrawLine(xx, yy, xx, yy) diff --git a/colorcircle2.go b/colorcircle2.go index d7f4cb7..e56486f 100644 --- a/colorcircle2.go +++ b/colorcircle2.go @@ -2,6 +2,7 @@ package generativeart import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart/common" "math" "math/rand" ) @@ -22,11 +23,11 @@ func (cc *colorCircle2) Generative(c *canva) { ctex := gg.NewContextForRGBA(c.img) for i := 0; i < cc.circleNum; i++ { - x := RandomRangeFloat64(0, float64(c.width)) - y := RandomRangeFloat64(0, float64(c.height)) + x := common.RandomRangeFloat64(0, float64(c.width)) + y := common.RandomRangeFloat64(0, float64(c.height)) - r1 := RandomRangeFloat64(50.0, float64(c.width)/4) - r2 := RandomRangeFloat64(10.0, float64(c.width)/3) + r1 := common.RandomRangeFloat64(50.0, float64(c.width)/4) + r2 := common.RandomRangeFloat64(10.0, float64(c.width)/3) cc.circle(ctex, c, x, y, r1, r2) if rand.Float64() < 0.3 { @@ -51,7 +52,7 @@ func (cc *colorCircle2) circle(ctex *gg.Context, c *canva, x, y, d, dx float64) ctex.SetColor(col) for i := 0; i < 150; i++ { - theta := RandomRangeFloat64(0, math.Pi*2) + theta := common.RandomRangeFloat64(0, math.Pi*2) xx := x + dd*0.5*math.Cos(theta) yy := y + dd*0.5*math.Sin(theta) ctex.DrawPoint(xx, yy, 0.51) diff --git a/utils.go b/common/utils.go similarity index 99% rename from utils.go rename to common/utils.go index b570551..6be0ee9 100644 --- a/utils.go +++ b/common/utils.go @@ -1,4 +1,4 @@ -package generativeart +package common import ( "image/color" diff --git a/utils_test.go b/common/utils_test.go similarity index 96% rename from utils_test.go rename to common/utils_test.go index 395e106..408423f 100644 --- a/utils_test.go +++ b/common/utils_test.go @@ -1,4 +1,4 @@ -package generativeart +package common import ( "math" diff --git a/contourline.go b/contourline.go new file mode 100644 index 0000000..72a7e55 --- /dev/null +++ b/contourline.go @@ -0,0 +1,46 @@ +package generativeart + +import ( + "github.com/aquilax/go-perlin" + "github.com/fogleman/gg" + "math" + "math/rand" +) + +type contourLine struct { + lineNum int +} + +func NewContourLine(lineNum int) *contourLine{ + return &contourLine{ + lineNum: lineNum, + } +} + +// Generative draws a contour line image. +func (cl *contourLine) Generative(c *canva) { + ctex := gg.NewContextForRGBA(c.img) + noise := perlin.NewPerlin(2, 2, 3, rand.Int63()) + + for i:=0; i float64(c.width) || x < 0 || y > float64(c.height) || y < 0 || rand.Float64() < 0.001 { + x = rand.Float64()*float64(c.width) + y = rand.Float64()*float64(c.height) + } + } + } +} diff --git a/dotLine.go b/dotLine.go index 3fd6d34..a0c8136 100644 --- a/dotLine.go +++ b/dotLine.go @@ -2,6 +2,7 @@ package generativeart import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart/common" "math/rand" ) @@ -35,13 +36,13 @@ func (d *dotLine) Generative(c *canva) { if d.randColor { ctex.SetColor(c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))]) } else { - ctex.SetRGBA255(RandomRangeInt(222, 255), RandomRangeInt(20, 222), 0, 255) + ctex.SetRGBA255(common.RandomRangeInt(222, 255), common.RandomRangeInt(20, 222), 0, 255) } for j := 0; j < n; j++ { newx := oldx + dir[rand.Intn(2)] newy := oldy + dir[rand.Intn(2)] - if Distance(float64(newx), float64(newy), float64(d.n/2), float64(d.n/2)) > float64(d.n/2-10) { + if common.Distance(float64(newx), float64(newy), float64(d.n/2), float64(d.n/2)) > float64(d.n/2-10) { newx = oldx newy = oldy } diff --git a/example/example_contourline.go b/example/example_contourline.go new file mode 100644 index 0000000..efd2a89 --- /dev/null +++ b/example/example_contourline.go @@ -0,0 +1,25 @@ +package main + +import ( + "github.com/jdxyw/generativeart" + "image/color" + "math/rand" + "time" +) + +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(800, 800) + c.SetBackground(color.RGBA{0x1a, 0x06, 0x33, 0xFF}) + c.FillBackground() + c.SetColorSchema(colors) + c.Draw(generativeart.NewContourLine(200)) + c.ToPNG("contourline.png") +} diff --git a/go.mod b/go.mod index d96a074..b67605d 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/jdxyw/generativeart go 1.16 require ( + github.com/aquilax/go-perlin v1.0.0 github.com/fogleman/gg v1.3.0 github.com/llgcode/draw2d v0.0.0-20200930101115-bfaf5d914d1e golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb // indirect diff --git a/go.sum b/go.sum index 3d829c6..32e8ff3 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/aquilax/go-perlin v1.0.0 h1:7KBttX3KwqipwhmIVE/B2cEZVYiOZpoE/q8HsS6HBoQ= +github.com/aquilax/go-perlin v1.0.0/go.mod h1:z9Rl7EM4BZY0Ikp2fEN1I5mKSOJ26HQpk0O2TBdN2HE= github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/go-gl/gl v0.0.0-20180407155706-68e253793080/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= diff --git a/janus.go b/janus.go index c481b43..8008b99 100644 --- a/janus.go +++ b/janus.go @@ -2,6 +2,7 @@ package generativeart import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart/common" "math" ) @@ -33,11 +34,11 @@ func (j *janus) Generative(c *canva) { ctex.Translate(float64(c.width/2), float64(c.height/2)) //theta += rand.Float64()*math.Pi/2 - theta := RandomRangeFloat64(math.Pi/4, 3*math.Pi/4) + theta := common.RandomRangeFloat64(math.Pi/4, 3*math.Pi/4) x1, y1 := math.Cos(theta)*r, math.Sin(theta)*r x2, y2 := -x1, -y1 - noise := RandomRangeFloat64(-math.Abs(y1), math.Abs(y1)) + noise := common.RandomRangeFloat64(-math.Abs(y1), math.Abs(y1)) y1 += noise y2 += noise diff --git a/randcircle.go b/randcircle.go index 9dfc627..1c42fe6 100644 --- a/randcircle.go +++ b/randcircle.go @@ -2,6 +2,7 @@ package generativeart import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart/common" "math" "math/rand" ) @@ -109,7 +110,7 @@ func (r *randCircle) Generative(c *canva) { continue } - distance := Distance(c1.x, c1.y, c2.x, c2.y) + distance := common.Distance(c1.x, c1.y, c2.x, c2.y) if distance <= c1.radius+c2.radius { cx := (c1.x + c2.x) / 2 diff --git a/randomshape.go b/randomshape.go index 41730a7..363c2fd 100644 --- a/randomshape.go +++ b/randomshape.go @@ -2,6 +2,7 @@ package generativeart import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart/common" "math" "math/rand" ) @@ -21,15 +22,15 @@ func (r *randomShape) Generative(c *canva) { ctex := gg.NewContextForRGBA(c.img) ctex.Translate(float64(c.width/2), float64(c.height/2)) - ctex.Rotate(RandomRangeFloat64(-1, 1) * math.Pi * 0.25) + ctex.Rotate(common.RandomRangeFloat64(-1, 1) * math.Pi * 0.25) ctex.Translate(-float64(c.width/2), -float64(c.height/2)) for i := 0; i < r.shapeNum; i++ { - x := RandomGaussian(0.5, 0.2) * float64(c.width) - y := RandomGaussian(0.5, 0.2) * float64(c.height) + x := common.RandomGaussian(0.5, 0.2) * float64(c.width) + y := common.RandomGaussian(0.5, 0.2) * float64(c.height) - w := RandomRangeFloat64(0, float64(c.width)/3)*RandomRangeFloat64(0, rand.Float64()) + 5.0 - h := w + RandomRangeFloat64(-1, 1)*3.0 + w := common.RandomRangeFloat64(0, float64(c.width)/3)*common.RandomRangeFloat64(0, rand.Float64()) + 5.0 + h := w + common.RandomRangeFloat64(-1, 1)*3.0 rnd := rand.Intn(4) theta := math.Pi * 2.0 * float64(rand.Intn(4)) / 4 @@ -50,7 +51,7 @@ func (r *randomShape) Generative(c *canva) { ctex.DrawRectangle(0, 0, w, h) } case 3: - ctex.DrawRectangle(0, 0, w*2, RandomRangeFloat64(2, 10)) + ctex.DrawRectangle(0, 0, w*2, common.RandomRangeFloat64(2, 10)) } ctex.Fill() ctex.Pop() diff --git a/silksky.go b/silksky.go index 045f52e..3d300b2 100644 --- a/silksky.go +++ b/silksky.go @@ -2,6 +2,7 @@ package generativeart import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart/common" "math/rand" ) @@ -30,7 +31,7 @@ func (s *silkSky) Generative(c *canva) { for i := 0; i < s.circleNum; i++ { for j := 0; j < s.circleNum; j++ { - hsv := HSV{ + hsv := common.HSV{ H: s.circleNum + j, S: i + 50, V: 70, @@ -39,7 +40,7 @@ func (s *silkSky) Generative(c *canva) { xn := (float64(i) + 0.5) * float64(c.width) / float64(s.circleNum) yn := (float64(j) + 0.5) * float64(c.height) / float64(s.circleNum) ctex.SetRGBA255(int(rgba.R), int(rgba.G), int(rgba.B), c.opts.alpha) - r := Distance(xn, yn, xm, ym) + r := common.Distance(xn, yn, xm, ym) ctex.DrawEllipse(xn, yn, r-s.sunRadius/2, r-s.sunRadius/2) ctex.Fill() } diff --git a/silksmoke.go b/silksmoke.go index 2eadc19..bb536f8 100644 --- a/silksmoke.go +++ b/silksmoke.go @@ -2,6 +2,7 @@ package generativeart import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart/common" "math/rand" ) @@ -51,7 +52,7 @@ func (s *sileSmoke) Generative(c *canva) { continue } - distance := Distance(c1.x, c1.y, c2.x, c2.y) + distance := common.Distance(c1.x, c1.y, c2.x, c2.y) if distance <= c1.radius+c2.radius { cx := (c1.x + c2.x) / 2 diff --git a/swirl.go b/swirl.go index 3b27f84..2b47689 100644 --- a/swirl.go +++ b/swirl.go @@ -2,6 +2,7 @@ package generativeart import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart/common" "math" ) @@ -34,7 +35,7 @@ func (s *swirl) Generative(c *canva) { 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) + x, y := common.ConvertCartesianToPixel(next.x, next.y, s.xaixs, s.yaixs, c.height, c.width) c.img.Set(x, y, cl) start = next }