From aec13501e114b981804a778cef62804c4dcdff65 Mon Sep 17 00:00:00 2001 From: Yongwei Xing Date: Tue, 16 Mar 2021 12:04:05 +0800 Subject: [PATCH] major refractor: move the arts to different folder and export the canve. --- circlegrid.go => arts/circlegrid.go | 29 +++++---- circleline.go => arts/circleline.go | 13 ++-- circleloop.go => arts/circleloop.go | 17 ++--- circleloop2.go => arts/circleloop2.go | 25 +++---- circlemove.go => arts/circlemove.go | 13 ++-- colorcircle.go => arts/colorcircle.go | 23 +++---- colorcircle2.go => arts/colorcircle2.go | 21 +++--- contourline.go => arts/contourline.go | 19 +++--- dotLine.go => arts/dotLine.go | 15 +++-- arts/dotswave.go | 49 ++++++++++++++ janus.go => arts/janus.go | 17 ++--- arts/julia.go | 46 +++++++++++++ maze.go => arts/maze.go | 15 +++-- noiseline.go => arts/noiseline.go | 21 +++--- oceanfish.go => arts/oceanfish.go | 23 +++---- pixelhole.go => arts/pixelhole.go | 23 +++---- pointRibbon.go => arts/pointRibbon.go | 15 +++-- randcircle.go => arts/randcircle.go | 19 +++--- randomshape.go => arts/randomshape.go | 19 +++--- silksky.go => arts/silksky.go | 17 ++--- silksmoke.go => arts/silksmoke.go | 21 +++--- solarflare.go => arts/solarflare.go | 13 ++-- spiralsquare.go => arts/spiralsquare.go | 17 ++--- squaregrid.go => arts/squaregrid.go | 21 +++--- swirl.go => arts/swirl.go | 43 +++++++------ dotswave.go | 48 -------------- example/example_circlegrid.go | 3 +- example/example_circleline.go | 3 +- example/example_circleloop.go | 3 +- example/example_circleloop2.go | 3 +- example/example_circlemove.go | 3 +- example/example_colorcircle.go | 3 +- example/example_colorcircle2.go | 3 +- example/example_contourline.go | 3 +- example/example_dotline.go | 3 +- example/example_dotswave.go | 3 +- example/example_gridsquare.go | 3 +- example/example_janus.go | 3 +- example/example_julia.go | 3 +- example/example_maze.go | 3 +- example/example_noiseline.go | 3 +- example/example_oceanfish.go | 3 +- example/example_pixelhole.go | 3 +- example/example_pointribbon.go | 3 +- example/example_randcircle.go | 3 +- example/example_randomshape.go | 3 +- example/example_silksky.go | 3 +- example/example_silksmoke.go | 3 +- example/example_solarflare.go | 3 +- example/example_spiralsquare.go | 3 +- example/example_swirl.go | 3 +- generativeart.go | 86 +++++++++++++++++++------ julia.go | 43 ------------- 53 files changed, 451 insertions(+), 355 deletions(-) rename circlegrid.go => arts/circlegrid.go (69%) rename circleline.go => arts/circleline.go (80%) rename circleloop.go => arts/circleloop.go (55%) rename circleloop2.go => arts/circleloop2.go (63%) rename circlemove.go => arts/circlemove.go (74%) rename colorcircle.go => arts/colorcircle.go (67%) rename colorcircle2.go => arts/colorcircle2.go (59%) rename contourline.go => arts/contourline.go (56%) rename dotLine.go => arts/dotLine.go (77%) create mode 100644 arts/dotswave.go rename janus.go => arts/janus.go (70%) create mode 100644 arts/julia.go rename maze.go => arts/maze.go (60%) rename noiseline.go => arts/noiseline.go (61%) rename oceanfish.go => arts/oceanfish.go (65%) rename pixelhole.go => arts/pixelhole.go (53%) rename pointRibbon.go => arts/pointRibbon.go (64%) rename randcircle.go => arts/randcircle.go (81%) rename randomshape.go => arts/randomshape.go (61%) rename silksky.go => arts/silksky.go (58%) rename silksmoke.go => arts/silksmoke.go (67%) rename solarflare.go => arts/solarflare.go (75%) rename spiralsquare.go => arts/spiralsquare.go (68%) rename squaregrid.go => arts/squaregrid.go (63%) rename swirl.go => arts/swirl.go (50%) delete mode 100644 dotswave.go delete mode 100644 julia.go diff --git a/circlegrid.go b/arts/circlegrid.go similarity index 69% rename from circlegrid.go rename to arts/circlegrid.go index 38e0c4a..b57a885 100644 --- a/circlegrid.go +++ b/arts/circlegrid.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "image/color" "math" @@ -21,21 +22,21 @@ func NewCircleGrid(circleNumMin, circleNumMax int) *circleGrid { } // Generative draws a circle grid image. -func (cg *circleGrid) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (cg *circleGrid) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) cg.grid(ctex, c) - ctex.Translate(float64(c.width)/2, float64(c.height)/2) + ctex.Translate(float64(c.Width())/2, float64(c.Height())/2) ctex.Scale(0.9, 0.9) - ctex.Translate(-float64(c.width)/2, -float64(c.height)/2) + ctex.Translate(-float64(c.Width())/2, -float64(c.Height())/2) seg := common.RandomRangeInt(cg.circleNumMin, cg.circleNumMax) - w := float64(c.width) / float64(seg) + w := float64(c.Width()) / float64(seg) for i := 0; i < seg; i++ { for j := 0; j < seg; j++ { x := float64(i)*w + w/2 y := float64(j)*w + w/2 - ctex.SetColor(c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))]) + ctex.SetColor(c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))]) ctex.DrawCircle(x, y, w/2*common.RandomRangeFloat64(0.1, 0.5)) ctex.Fill() cg.draw(ctex, c, x, y, w/2*common.RandomRangeFloat64(0.6, 0.95)) @@ -43,14 +44,14 @@ func (cg *circleGrid) Generative(c *canva) { } } -func (cg *circleGrid) draw(ctex *gg.Context, c *canva, x, y, r float64) { +func (cg *circleGrid) draw(ctex *gg.Context, c *generativeart.Canva, x, y, r float64) { rnd := rand.Intn(4) - col := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))] + col := c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))] ctex.Push() ctex.Translate(x, y) ctex.Rotate(float64(rand.Intn(10))) ctex.SetColor(col) - ctex.SetLineWidth(c.opts.lineWidth) + ctex.SetLineWidth(c.Opts().LineWidth()) switch rnd { case 0: @@ -89,19 +90,19 @@ func (cg *circleGrid) draw(ctex *gg.Context, c *canva, x, y, r float64) { ctex.Pop() } -func (cg *circleGrid) grid(ctex *gg.Context, c *canva) { +func (cg *circleGrid) grid(ctex *gg.Context, c *generativeart.Canva) { var segment int = 100 - w := float64(c.width) / float64(segment) + w := float64(c.Width()) / float64(segment) ctex.SetColor(color.RGBA{255, 255, 255, 255}) ctex.SetLineWidth(0.6) for i := 0; i < segment; i++ { - ctex.DrawLine(0, float64(i)*w, float64(c.width), float64(i)*w) + ctex.DrawLine(0, float64(i)*w, float64(c.Width()), float64(i)*w) ctex.Stroke() } for j := 0; j < segment; j++ { - ctex.DrawLine(float64(j)*w, 0, float64(j)*w, float64(c.height)) + ctex.DrawLine(float64(j)*w, 0, float64(j)*w, float64(c.Height())) ctex.Stroke() } } diff --git a/circleline.go b/arts/circleline.go similarity index 80% rename from circleline.go rename to arts/circleline.go index c991da5..fe577d5 100644 --- a/circleline.go +++ b/arts/circleline.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math" "math/rand" @@ -30,15 +31,15 @@ func NewCircleLine(step float64, lineNum int, radius, xaixs, yaixs float64) *cir } // Generative draws a cirle line image. -func (cl *circleLine) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) - ctex.SetLineWidth(c.opts.lineWidth) - ctex.SetColor(c.opts.lineColor) +func (cl *circleLine) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) + ctex.SetLineWidth(c.Opts().LineWidth()) + ctex.SetColor(c.Opts().LineColor()) var points []point for theta := -math.Pi; theta <= math.Pi; theta += cl.step { x := cl.radius * math.Cos(theta) y := cl.radius * math.Sin(theta) - xi, yi := common.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/circleloop.go b/arts/circleloop.go similarity index 55% rename from circleloop.go rename to arts/circleloop.go index c5ea017..7e89672 100644 --- a/circleloop.go +++ b/arts/circleloop.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "math" ) @@ -16,20 +17,20 @@ func NewCircleLoop(radius float64) *circleLoop { } // Generative draws a Circle Loop images. -func (cl *circleLoop) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (cl *circleLoop) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) r := cl.radius var theta float64 = 0 - for i := 0; i < c.opts.nIters; i++ { + for i := 0; i < c.Opts().NIters(); i++ { ctex.Push() - ctex.Translate(float64(c.width/2), float64(c.height/2)) + ctex.Translate(float64(c.Width()/2), float64(c.Height()/2)) x := cl.radius * math.Cos(gg.Radians(theta)) y := cl.radius * math.Sin(gg.Radians(theta*2)) - ctex.SetLineWidth(c.opts.lineWidth) - ctex.SetColor(c.opts.lineColor) - ctex.SetRGBA255(int(c.opts.lineColor.R), int(c.opts.lineColor.G), int(c.opts.lineColor.B), c.opts.alpha) + ctex.SetLineWidth(c.Opts().LineWidth()) + ctex.SetColor(c.Opts().LineColor()) + ctex.SetRGBA255(int(c.Opts().LineColor().R), int(c.Opts().LineColor().G), int(c.Opts().LineColor().B), c.Opts().Alpha()) ctex.DrawEllipse(x, y, r/2, r/2) ctex.Stroke() ctex.Pop() diff --git a/circleloop2.go b/arts/circleloop2.go similarity index 63% rename from circleloop2.go rename to arts/circleloop2.go index 87bd1fb..b23f011 100644 --- a/circleloop2.go +++ b/arts/circleloop2.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math" "math/rand" @@ -20,13 +21,13 @@ func NewCircleLoop2(depth int) *circleLoop2 { } // Generative draws a circle composed by many colored circles. -func (cl *circleLoop2) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) - ctex.Translate(float64(c.width)/2, float64(c.height)/2) - cl.recursionDraw(ctex, c, float64(c.width), cl.depth) +func (cl *circleLoop2) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) + ctex.Translate(float64(c.Width())/2, float64(c.Height())/2) + cl.recursionDraw(ctex, c, float64(c.Width()), cl.depth) } -func (cl *circleLoop2) recursionDraw(ctex *gg.Context, c *canva, x float64, depth int) { +func (cl *circleLoop2) recursionDraw(ctex *gg.Context, c *generativeart.Canva, x float64, depth int) { if depth <= 0 { return } @@ -37,7 +38,7 @@ func (cl *circleLoop2) recursionDraw(ctex *gg.Context, c *canva, x float64, dept cl.recursionDraw(ctex, c, 3*x/4.0, depth-1) } -func (cl *circleLoop2) draw(ctex *gg.Context, c *canva, x float64) { +func (cl *circleLoop2) draw(ctex *gg.Context, c *generativeart.Canva, x float64) { var lw float64 if rand.Float64() < 0.8 { lw = 1 @@ -50,11 +51,11 @@ func (cl *circleLoop2) draw(ctex *gg.Context, c *canva, x float64) { noise = math.Pow(noise, 0.5) a2 := common.Remap(noise, 0.15, 0.85, 0.1, 0.6) - px := math.Pow(x/float64(c.height), a2) * float64(c.height) - py := math.Pow(1-x/float64(c.height), a2)*float64(c.height) - - common.RandomRangeFloat64(0, common.RandomRangeFloat64(float64(c.height)*0.18, common.RandomRangeFloat64(float64(c.height)*0.18, float64(c.height)*0.7))) + px := math.Pow(x/float64(c.Height()), a2) * float64(c.Height()) + py := math.Pow(1-x/float64(c.Height()), a2)*float64(c.Height()) - + common.RandomRangeFloat64(0, common.RandomRangeFloat64(float64(c.Height())*0.18, common.RandomRangeFloat64(float64(c.Height())*0.18, float64(c.Height())*0.7))) - cls := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))] + cls := c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))] ctex.SetColor(cls) nCircles := common.RandomRangeInt(1, 6) if rand.Float64() < 0.03 { @@ -76,5 +77,5 @@ func (cl *circleLoop2) draw(ctex *gg.Context, c *canva, x float64) { } ctex.Stroke() } - ctex.Rotate(x / float64(c.height) * 0.2) + ctex.Rotate(x / float64(c.Height()) * 0.2) } diff --git a/circlemove.go b/arts/circlemove.go similarity index 74% rename from circlemove.go rename to arts/circlemove.go index ff67389..17beeb5 100644 --- a/circlemove.go +++ b/arts/circlemove.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math" "math/rand" @@ -18,8 +19,8 @@ func NewCircleMove(circleNum int) *circleMove { } // Generative draws a sircle moving images. -func (cm *circleMove) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (cm *circleMove) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) ctex.SetLineWidth(0.3) noise := common.NewPerlinNoise() cl := rand.Intn(255) @@ -30,9 +31,9 @@ func (cm *circleMove) Generative(c *canva) { for j := 0.0; j < np; j += 1.0 { theta := common.Remap(j, 0, np, 0, math.Pi*2) cx := float64(i)*3 - 200.0 - cy := float64(c.height)/2 + math.Sin(float64(i)/50)*float64(c.height)/12.0 - xx := math.Cos(theta+cx/10)*float64(c.height)/6.0 - yy := math.Sin(theta+cx/10)*float64(c.height)/6.0 + cy := float64(c.Height())/2 + math.Sin(float64(i)/50)*float64(c.Height())/12.0 + xx := math.Cos(theta+cx/10)*float64(c.Height())/6.0 + yy := math.Sin(theta+cx/10)*float64(c.Height())/6.0 p := common.NewVector(xx, yy) xx = (xx + cx) / 150 yy = (yy + cy) / 150 diff --git a/colorcircle.go b/arts/colorcircle.go similarity index 67% rename from colorcircle.go rename to arts/colorcircle.go index 207ff02..86cb77b 100644 --- a/colorcircle.go +++ b/arts/colorcircle.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math" "math/rand" @@ -18,14 +19,14 @@ func NewColorCircle(circleNum int) *colorCircle { } // Generative draws a color circle images. -func (cc *colorCircle) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (cc *colorCircle) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) for i := 0; i < cc.circleNum; i++ { rnd := rand.Intn(3) - 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 + 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) } @@ -34,7 +35,7 @@ func (cc *colorCircle) Generative(c *canva) { cc.drawCircleV1(ctex, c, x, y, s) case 1: ctex.SetLineWidth(common.RandomRangeFloat64(0, 1)) - ctex.SetColor(c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))]) + ctex.SetColor(c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))]) ctex.DrawCircle(x, y, common.RandomRangeFloat64(0, s)/2) ctex.Stroke() case 2: @@ -43,10 +44,10 @@ func (cc *colorCircle) Generative(c *canva) { } } -func (cc *colorCircle) drawCircleV1(ctex *gg.Context, c *canva, x, y, s float64) { +func (cc *colorCircle) drawCircleV1(ctex *gg.Context, c *generativeart.Canva, x, y, s float64) { n := common.RandomRangeInt(4, 30) cs := common.RandomRangeFloat64(2, 8) - ctex.SetColor(c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))]) + ctex.SetColor(c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))]) ctex.Push() ctex.Translate(x, y) for a := 0.0; a < math.Pi*2.0; a += math.Pi * 2.0 / float64(n) { @@ -56,8 +57,8 @@ func (cc *colorCircle) drawCircleV1(ctex *gg.Context, c *canva, x, y, s float64) ctex.Pop() } -func (cc *colorCircle) drawCircleV2(ctex *gg.Context, c *canva, x, y, s float64) { - cl := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))] +func (cc *colorCircle) drawCircleV2(ctex *gg.Context, c *generativeart.Canva, x, y, s float64) { + cl := c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))] ctex.SetLineWidth(1.0) sx := s * common.RandomRangeFloat64(0.1, 0.55) for j := 0.0001; j < sx; j++ { diff --git a/colorcircle2.go b/arts/colorcircle2.go similarity index 59% rename from colorcircle2.go rename to arts/colorcircle2.go index e56486f..7af7db9 100644 --- a/colorcircle2.go +++ b/arts/colorcircle2.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math" "math/rand" @@ -19,19 +20,19 @@ func NewColorCircle2(circleNum int) *colorCircle2 { } // Generative draws a color circle image. -func (cc *colorCircle2) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (cc *colorCircle2) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) for i := 0; i < cc.circleNum; i++ { - x := common.RandomRangeFloat64(0, float64(c.width)) - y := common.RandomRangeFloat64(0, float64(c.height)) + x := common.RandomRangeFloat64(0, float64(c.Width())) + y := common.RandomRangeFloat64(0, float64(c.Height())) - r1 := common.RandomRangeFloat64(50.0, float64(c.width)/4) - r2 := common.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 { - col := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))] + col := c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))] ctex.SetColor(col) ctex.DrawCircle(x, y, r1/2.0) ctex.Fill() @@ -39,8 +40,8 @@ func (cc *colorCircle2) Generative(c *canva) { } } -func (cc *colorCircle2) circle(ctex *gg.Context, c *canva, x, y, d, dx float64) { - col := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))] +func (cc *colorCircle2) circle(ctex *gg.Context, c *generativeart.Canva, x, y, d, dx float64) { + col := c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))] for j := 0.0; j < dx; j += 1.0 { dd := d + j*2.0 diff --git a/contourline.go b/arts/contourline.go similarity index 56% rename from contourline.go rename to arts/contourline.go index 42e115b..a9f45b0 100644 --- a/contourline.go +++ b/arts/contourline.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math" "math/rand" @@ -19,13 +20,13 @@ func NewContourLine(lineNum int) *contourLine { } // Generative draws a contour line image. -func (cl *contourLine) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (cl *contourLine) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) noise := common.NewPerlinNoise() for i := 0; i < cl.lineNum; i++ { - cl := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))] - x := rand.Float64() * float64(c.width) - y := rand.Float64() * float64(c.height) + cl := c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))] + x := rand.Float64() * float64(c.Width()) + y := rand.Float64() * float64(c.Height()) for j := 0; j < 1500; j++ { @@ -37,9 +38,9 @@ func (cl *contourLine) Generative(c *canva) { ctex.DrawEllipse(x, y, 2, 2) ctex.Fill() - if x > 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) + if x > 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/arts/dotLine.go similarity index 77% rename from dotLine.go rename to arts/dotLine.go index a0c8136..6fb9174 100644 --- a/dotLine.go +++ b/arts/dotLine.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math/rand" ) @@ -23,18 +24,18 @@ func NewDotLine(n int, ras, canv float64, randColor bool) *dotLine { } } -func (d *dotLine) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (d *dotLine) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) - ctex.SetLineWidth(c.opts.lineWidth) + ctex.SetLineWidth(c.Opts().LineWidth()) var dir []int = []int{-1, 1} - for i := 0; i < c.opts.nIters; i++ { + for i := 0; i < c.Opts().NIters(); i++ { oldx := rand.Intn(d.n - 1) oldy := rand.Intn(d.n - 1) n := rand.Intn(7) if d.randColor { - ctex.SetColor(c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))]) + ctex.SetColor(c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))]) } else { ctex.SetRGBA255(common.RandomRangeInt(222, 255), common.RandomRangeInt(20, 222), 0, 255) } @@ -47,7 +48,7 @@ func (d *dotLine) Generative(c *canva) { newy = oldy } 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.DrawEllipse(float64(oldx)*d.ras+d.canv, float64(oldy)*d.ras+d.canv, c.Opts().LineWidth(), c.Opts().LineWidth()) ctex.Fill() continue } diff --git a/arts/dotswave.go b/arts/dotswave.go new file mode 100644 index 0000000..6672eea --- /dev/null +++ b/arts/dotswave.go @@ -0,0 +1,49 @@ +package arts + +import ( + "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/common" + "math" + "math/rand" +) + +type dotsWave struct { + dotsN int +} + +// NewDotsWave returns a dotsWave object. +func NewDotsWave(dotsN int) *dotsWave { + return &dotsWave{ + dotsN: dotsN, + } +} + +// Generative draws a dots wave images. +func (d *dotsWave) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) + noise := common.NewPerlinNoise() + for i := 0; i < d.dotsN; i++ { + x := common.RandomRangeFloat64(-0.1, 1.1) * float64(c.Width()) + y := common.RandomRangeFloat64(-0.1, 1.1) * float64(c.Height()) + + num := common.RandomRangeFloat64(100, 1000) + r := rand.Float64() * float64(c.Width()) * 0.15 * rand.Float64() + ind := common.RandomRangeFloat64(1, 8) + + ctex.Push() + ctex.Translate(x, y) + ctex.Rotate(float64(rand.Intn(8)) * math.Pi / 4) + rand.Shuffle(len(c.Opts().ColorSchema()), func(i, j int) { + c.Opts().ColorSchema()[i], c.Opts().ColorSchema()[j] = c.Opts().ColorSchema()[j], c.Opts().ColorSchema()[i] + }) + for j := 0.0; j < num; j += ind { + s := float64(c.Width()) * 0.15 * common.RandomRangeFloat64(0, common.RandomRangeFloat64(0, common.RandomRangeFloat64(0, common.RandomRangeFloat64(0, common.RandomRangeFloat64(0, common.RandomRangeFloat64(0, rand.Float64())))))) + ci := int(float64(len(c.Opts().ColorSchema())) * noise.Noise3D(j*0.01, x, y)) + ctex.SetColor(c.Opts().ColorSchema()[ci]) + ctex.DrawCircle(j, r*math.Sin(j*0.05), s*2/3) + ctex.Fill() + } + ctex.Pop() + } +} diff --git a/janus.go b/arts/janus.go similarity index 70% rename from janus.go rename to arts/janus.go index 8008b99..372ad44 100644 --- a/janus.go +++ b/arts/janus.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math" ) @@ -21,17 +22,17 @@ func NewJanus(n int, decay float64) *janus { // Generative draws a janus image // TODO not finished. -func (j *janus) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) - //ctex.SetColor(c.opts.foreground) +func (j *janus) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) + //ctex.SetColor(c.Opts().Foreground()) s := 220.0 r := 0.3 for i := 0; i < j.n; i++ { - //k := rand.Intn(len(c.opts.colorSchema)) + //k := rand.Intn(len(c.Opts().ColorSchema())) k := i ctex.Push() - ctex.Translate(float64(c.width/2), float64(c.height/2)) + ctex.Translate(float64(c.Width()/2), float64(c.Height()/2)) //theta += rand.Float64()*math.Pi/2 theta := common.RandomRangeFloat64(math.Pi/4, 3*math.Pi/4) @@ -47,10 +48,10 @@ func (j *janus) Generative(c *canva) { ctex.Scale(s, s) //r = r * 0.836 ctex.DrawArc(x1, y1, 1.0, math.Pi*3/2+theta, math.Pi*5/2+theta) - ctex.SetColor(c.opts.colorSchema[k]) + ctex.SetColor(c.Opts().ColorSchema()[k]) ctex.Fill() ctex.DrawArc(x2, y2, 1.0, math.Pi/2+theta, math.Pi*3/2+theta) - ctex.SetColor(c.opts.colorSchema[k]) + ctex.SetColor(c.Opts().ColorSchema()[k]) ctex.Fill() ctex.Pop() } diff --git a/arts/julia.go b/arts/julia.go new file mode 100644 index 0000000..2cbaff2 --- /dev/null +++ b/arts/julia.go @@ -0,0 +1,46 @@ +package arts + +import ( + "github.com/jdxyw/generativeart" + "math/cmplx" +) + +// GenFunc defines a func type used by julia set. +type GenFunc func(complex128) complex128 + +type julia struct { + fn GenFunc + maxz float64 + xaixs, yaixs float64 +} + +func NewJulia(formula GenFunc, maxz, xaixs, yaixs float64) *julia { + return &julia{ + fn: formula, + maxz: maxz, + xaixs: xaixs, + yaixs: yaixs, + } +} + +// Generative draws a julia set. +func (j *julia) Generative(c *generativeart.Canva) { + n := len(c.Opts().ColorSchema()) + if n > 255 { + n = 255 + } + + for i := 0; i <= c.Width(); i++ { + for k := 0; k <= c.Height(); k++ { + nit := 0 + z := complex(float64(i)/float64(c.Width())*2.0*j.yaixs-j.yaixs, float64(k)/float64(c.Height())*2.0*j.yaixs-j.yaixs) + + for cmplx.Abs(z) <= j.maxz && nit < c.Opts().NIters() { + z = j.fn(z) + nit += 1 + } + idx := uint8(nit*255/c.Opts().NIters()) % uint8(n) + c.Img().Set(i, k, c.Opts().ColorSchema()[idx]) + } + } +} diff --git a/maze.go b/arts/maze.go similarity index 60% rename from maze.go rename to arts/maze.go index f2177c0..53f6baa 100644 --- a/maze.go +++ b/arts/maze.go @@ -1,6 +1,7 @@ -package generativeart +package arts import ( + "github.com/jdxyw/generativeart" "math/rand" "github.com/fogleman/gg" @@ -18,12 +19,12 @@ func NewMaze(step int) *maze { } // Generative draws a random maze image. -func (m *maze) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) - ctex.SetColor(c.opts.lineColor) - ctex.SetLineWidth(c.opts.lineWidth) - for x := 0; x < c.width; x += m.step { - for y := 0; y < c.height; y += m.step { +func (m *maze) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) + ctex.SetColor(c.Opts().LineColor()) + ctex.SetLineWidth(c.Opts().LineWidth()) + for x := 0; x < c.Width(); x += m.step { + for y := 0; y < c.Height(); y += m.step { if rand.Float32() > 0.5 { ctex.DrawLine(float64(x), float64(y), float64(x+m.step), float64(y+m.step)) } else { diff --git a/noiseline.go b/arts/noiseline.go similarity index 61% rename from noiseline.go rename to arts/noiseline.go index c628acb..bb866a6 100644 --- a/noiseline.go +++ b/arts/noiseline.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math" "math/rand" @@ -19,16 +20,16 @@ func NewNoiseLine(n int) *noiseLine { } // Generative draws a noise line image. -func (nl *noiseLine) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (nl *noiseLine) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) noise := common.NewPerlinNoise() ctex.SetColor(common.Black) for i := 0; i < 80; i++ { - x := rand.Float64() * float64(c.width) - y := rand.Float64() * float64(c.height) + x := rand.Float64() * float64(c.Width()) + y := rand.Float64() * float64(c.Height()) - s := rand.Float64() * float64(c.width) / 8 + s := rand.Float64() * float64(c.Width()) / 8 ctex.SetLineWidth(0.5) ctex.DrawEllipse(x, y, s, s) ctex.Stroke() @@ -36,10 +37,10 @@ func (nl *noiseLine) Generative(c *canva) { t := rand.Float64() * 10 for i := 0; i < nl.n; i++ { - x := common.RandomRangeFloat64(-0.5, 1.5) * float64(c.width) - y := common.RandomRangeFloat64(-0.5, 1.5) * float64(c.height) - cl := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))] - cl.A = uint8(c.opts.alpha) + x := common.RandomRangeFloat64(-0.5, 1.5) * float64(c.Width()) + y := common.RandomRangeFloat64(-0.5, 1.5) * float64(c.Height()) + cl := c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))] + cl.A = uint8(c.Opts().Alpha()) l := 400 for j := 0; j < l; j++ { diff --git a/oceanfish.go b/arts/oceanfish.go similarity index 65% rename from oceanfish.go rename to arts/oceanfish.go index e7e6157..4819178 100644 --- a/oceanfish.go +++ b/arts/oceanfish.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math" "math/rand" @@ -21,8 +22,8 @@ func NewOceanFish(lineNum, fishNum int) *oceanFish { } // Generative draws a ocean and fish images. -func (o *oceanFish) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (o *oceanFish) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) o.drawlines(ctex, c) @@ -30,12 +31,12 @@ func (o *oceanFish) Generative(c *canva) { ctex.Push() theta := float64(360*i) / float64(o.fishNum) - r := float64(c.width) / 4.0 + r := float64(c.Width()) / 4.0 ctex.Push() - ctex.Translate(float64(c.width/2)+r*math.Cos(gg.Radians(theta)), float64(c.height/2)+r*math.Sin(gg.Radians(theta))) + ctex.Translate(float64(c.Width()/2)+r*math.Cos(gg.Radians(theta)), float64(c.Height()/2)+r*math.Sin(gg.Radians(theta))) ctex.Rotate(gg.Radians(theta + 90)) - o.drawfish(ctex, c, 0, 0, float64(c.width)/10) + o.drawfish(ctex, c, 0, 0, float64(c.Width())/10) ctex.Pop() ctex.Clip() @@ -46,18 +47,18 @@ func (o *oceanFish) Generative(c *canva) { } } -func (o *oceanFish) drawlines(ctx *gg.Context, c *canva) { +func (o *oceanFish) drawlines(ctx *gg.Context, c *generativeart.Canva) { for i := 0; i < o.lineNum; i++ { - cl := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))] + cl := c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))] ctx.SetColor(cl) ctx.SetLineWidth(common.RandomRangeFloat64(3, 20)) - y := rand.Float64() * float64(c.height) - ctx.DrawLine(0, y+common.RandomRangeFloat64(-50, 50), float64(c.width), y+common.RandomRangeFloat64(-50, 50)) + y := rand.Float64() * float64(c.Height()) + ctx.DrawLine(0, y+common.RandomRangeFloat64(-50, 50), float64(c.Width()), y+common.RandomRangeFloat64(-50, 50)) ctx.Stroke() } } -func (o *oceanFish) drawfish(ctex *gg.Context, c *canva, ox, oy, r float64) { +func (o *oceanFish) drawfish(ctex *gg.Context, c *generativeart.Canva, ox, oy, r float64) { ctex.Push() ctex.Translate(ox, oy) ctex.Rotate(gg.Radians(180)) diff --git a/pixelhole.go b/arts/pixelhole.go similarity index 53% rename from pixelhole.go rename to arts/pixelhole.go index 791404f..0e25945 100644 --- a/pixelhole.go +++ b/arts/pixelhole.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math" "math/rand" @@ -21,30 +22,30 @@ func NewPixelHole(dotN int) *pixelHole { } // Generative draws a pixel hole images. -func (p *pixelHole) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) - for i := 0.0; i < float64(c.opts.nIters); i += 1.0 { +func (p *pixelHole) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) + for i := 0.0; i < float64(c.Opts().NIters()); i += 1.0 { ctex.Push() - ctex.Translate(float64(c.width)/2, float64(c.height)/2) + 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) { +func (p *pixelHole) draw(ctex *gg.Context, c *generativeart.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) + 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) + 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 + 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) diff --git a/pointRibbon.go b/arts/pointRibbon.go similarity index 64% rename from pointRibbon.go rename to arts/pointRibbon.go index 116ba60..3755db2 100644 --- a/pointRibbon.go +++ b/arts/pointRibbon.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "math" ) @@ -18,17 +19,17 @@ func NewPointRibbon(r float64) *pointRibbon { // Generative draws a point ribbon image. // TODO: make the point as parameters. -func (s *pointRibbon) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) - ctex.SetLineWidth(c.opts.lineWidth) +func (s *pointRibbon) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) + ctex.SetLineWidth(c.Opts().LineWidth()) var t float64 var dt = 0.0001 - for i := 0; i < c.opts.nIters; i++ { + for i := 0; i < c.Opts().NIters(); i++ { delta := 2.0*s.r*math.Cos(4.0*dt*t) + s.r*math.Cos(t) ctex.SetRGBA255(int(delta), int(2*s.r*math.Sin(t)-s.r*math.Cos(3*dt*t)), 100, 10) - ctex.DrawPoint(2*s.r*math.Sin(2*t*dt)+s.r*math.Cos(t*dt)+float64(c.width/2), - 2*s.r*math.Sin(t*dt)-s.r*math.Sin(5*t)+float64(c.height/2), 1.0) + ctex.DrawPoint(2*s.r*math.Sin(2*t*dt)+s.r*math.Cos(t*dt)+float64(c.Width()/2), + 2*s.r*math.Sin(t*dt)-s.r*math.Sin(5*t)+float64(c.Height()/2), 1.0) ctex.Stroke() t += 0.01 dt += 0.1 diff --git a/randcircle.go b/arts/randcircle.go similarity index 81% rename from randcircle.go rename to arts/randcircle.go index 1c42fe6..92f35fd 100644 --- a/randcircle.go +++ b/arts/randcircle.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math" "math/rand" @@ -90,20 +91,20 @@ func circleSliceUpdate(cs []circle, w, h int) []circle { } // Generative draws a random circles image. -func (r *randCircle) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (r *randCircle) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) - for j := 0; j < c.opts.nIters; j++ { + for j := 0; j < c.Opts().NIters(); j++ { cn := rand.Intn(r.maxCircle) + int(r.maxCircle/3) - circles := newCircleSlice(cn, c.width, c.height, r.minSteps, r.maxSteps, r.minRadius, r.maxRadius) + circles := newCircleSlice(cn, c.Width(), c.Height(), r.minSteps, r.maxSteps, r.minRadius, r.maxRadius) for i := 0; i < r.maxStepsPerCircle; i++ { for _, c1 := range circles { for _, c2 := range circles { - cl := c.opts.lineColor + cl := c.Opts().LineColor() if r.isRandColor { - cl = c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))] + cl = c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))] } if c1 == c2 { @@ -117,14 +118,14 @@ func (r *randCircle) Generative(c *canva) { cy := (c1.y + c2.y) / 2 ctex.SetRGBA255(int(cl.R), int(cl.G), int(cl.B), 30) - ctex.SetLineWidth(c.opts.lineWidth) + ctex.SetLineWidth(c.Opts().LineWidth()) ctex.DrawEllipse(cx, cy, distance/2, distance/2) ctex.Stroke() } } } - circles = circleSliceUpdate(circles, c.width, c.height) + circles = circleSliceUpdate(circles, c.Width(), c.Height()) } } } diff --git a/randomshape.go b/arts/randomshape.go similarity index 61% rename from randomshape.go rename to arts/randomshape.go index 363c2fd..4a0df68 100644 --- a/randomshape.go +++ b/arts/randomshape.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math" "math/rand" @@ -18,18 +19,18 @@ func NewRandomShape(shapeNum int) *randomShape { } // Generative draws a random shape image. -func (r *randomShape) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (r *randomShape) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) - ctex.Translate(float64(c.width/2), float64(c.height/2)) + ctex.Translate(float64(c.Width()/2), float64(c.Height()/2)) ctex.Rotate(common.RandomRangeFloat64(-1, 1) * math.Pi * 0.25) - ctex.Translate(-float64(c.width/2), -float64(c.height/2)) + ctex.Translate(-float64(c.Width()/2), -float64(c.Height()/2)) for i := 0; i < r.shapeNum; i++ { - x := common.RandomGaussian(0.5, 0.2) * float64(c.width) - y := common.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 := common.RandomRangeFloat64(0, float64(c.width)/3)*common.RandomRangeFloat64(0, rand.Float64()) + 5.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) @@ -38,7 +39,7 @@ func (r *randomShape) Generative(c *canva) { ctex.Push() ctex.Translate(x, y) ctex.Rotate(theta) - ctex.SetColor(c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))]) + ctex.SetColor(c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))]) switch rnd { case 0: ctex.DrawCircle(0, 0, w/2) diff --git a/silksky.go b/arts/silksky.go similarity index 58% rename from silksky.go rename to arts/silksky.go index 3d300b2..93ce432 100644 --- a/silksky.go +++ b/arts/silksky.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math/rand" ) @@ -20,10 +21,10 @@ func NewSilkSky(circleNum int, sunRadius float64) *silkSky { } // Generative draws a silk sky image. -func (s *silkSky) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) - xm := float64(rand.Intn(c.width/5)) + float64(c.width*4/5-c.width/5) - ym := float64(rand.Intn(c.height/5)) + float64(c.height*4/5-c.height/5) +func (s *silkSky) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) + xm := float64(rand.Intn(c.Width()/5)) + float64(c.Width()*4/5-c.Width()/5) + ym := float64(rand.Intn(c.Height()/5)) + float64(c.Height()*4/5-c.Height()/5) mh := s.circleNum*2 + 2 ms := s.circleNum*2 + 50 @@ -37,9 +38,9 @@ func (s *silkSky) Generative(c *canva) { V: 70, } rgba := hsv.ToRGB(mh, ms, mv) - 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) + 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 := 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/arts/silksmoke.go similarity index 67% rename from silksmoke.go rename to arts/silksmoke.go index bb536f8..e7d93ec 100644 --- a/silksmoke.go +++ b/arts/silksmoke.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math/rand" ) @@ -29,23 +30,23 @@ func NewSilkSmoke(mc, msp int, minStep, maxStep, minRadius, maxRadius float64, i } // Generative draws a silk smoke image. -func (s *sileSmoke) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (s *sileSmoke) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) cn := rand.Intn(s.maxCircle) + int(s.maxCircle/3) - circles := newCircleSlice(cn, c.width, c.height, s.minSteps, s.maxSteps, s.minRadius, s.maxRadius) + circles := newCircleSlice(cn, c.Width(), c.Height(), s.minSteps, s.maxSteps, s.minRadius, s.maxRadius) for i := 0; i < s.maxStepsPerCircle; i++ { ctex.SetRGBA255(0, 0, 0, 5) - ctex.DrawRectangle(0, 0, float64(c.width), float64(c.height)) + ctex.DrawRectangle(0, 0, float64(c.Width()), float64(c.Height())) ctex.Fill() for _, c1 := range circles { for _, c2 := range circles { - cl := c.opts.lineColor + cl := c.Opts().LineColor() if s.isRandColor { - cl = c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))] + cl = c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))] } if c1 == c2 { @@ -58,8 +59,8 @@ func (s *sileSmoke) Generative(c *canva) { cx := (c1.x + c2.x) / 2 cy := (c1.y + c2.y) / 2 - ctex.SetRGBA255(int(cl.R), int(cl.G), int(cl.B), c.opts.alpha) - ctex.SetLineWidth(c.opts.lineWidth) + ctex.SetRGBA255(int(cl.R), int(cl.G), int(cl.B), c.Opts().Alpha()) + ctex.SetLineWidth(c.Opts().LineWidth()) ctex.LineTo(c1.x, c1.y) ctex.LineTo(c2.x, c2.y) @@ -71,6 +72,6 @@ func (s *sileSmoke) Generative(c *canva) { } } - circles = circleSliceUpdate(circles, c.width, c.height) + circles = circleSliceUpdate(circles, c.Width(), c.Height()) } } diff --git a/solarflare.go b/arts/solarflare.go similarity index 75% rename from solarflare.go rename to arts/solarflare.go index 770683d..ca0fa70 100644 --- a/solarflare.go +++ b/arts/solarflare.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "image" "image/color" @@ -17,7 +18,7 @@ func NewSolarFlare() *solarFlare { } // Generative draws a solar flare images. -func (o *solarFlare) Generative(c *canva) { +func (o *solarFlare) Generative(c *generativeart.Canva) { var xOffset, yOffset float64 var offsetInc = 0.006 var inc = 1.0 @@ -30,14 +31,14 @@ func (o *solarFlare) Generative(c *canva) { nPoints := int(2 * math.Pi * r) nPoints = common.MinInt(nPoints, 500) - img := image.NewRGBA(image.Rect(0, 0, c.width, c.height)) + img := image.NewRGBA(image.Rect(0, 0, c.Width(), c.Height())) draw.Draw(img, img.Bounds(), &image.Uniform{color.Black}, image.ZP, draw.Src) ctex := gg.NewContextForRGBA(img) ctex.Push() - ctex.Translate(float64(c.width/2), float64(c.height/2)) + ctex.Translate(float64(c.Width()/2), float64(c.Height()/2)) ctex.SetLineWidth(1.0) - ctex.SetColor(c.opts.lineColor) + ctex.SetColor(c.Opts().LineColor()) for j := 0.0; j < float64(nPoints+1); j += 1.0 { a := j / float64(nPoints) * math.Pi * 2 @@ -51,7 +52,7 @@ func (o *solarFlare) Generative(c *canva) { ctex.Stroke() ctex.Pop() - c.img = common.Blend(img, c.img, common.Add) + //c.Img() = common.Blend(img, c.Img(), common.Add) xOffset += offsetInc yOffset += offsetInc r *= m diff --git a/spiralsquare.go b/arts/spiralsquare.go similarity index 68% rename from spiralsquare.go rename to arts/spiralsquare.go index 4cc4ff2..64490b4 100644 --- a/spiralsquare.go +++ b/arts/spiralsquare.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "math/rand" ) @@ -23,14 +24,14 @@ func NewSpiralSquare(squareNum int, rectSide, decay float64, randColor bool) *sp } // Generative draws a spiral square images. -func (s *spiralSquare) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (s *spiralSquare) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) sl := s.rectSide theta := rand.Intn(360) + 1 for i := 0; i < s.squareNum; i++ { ctex.Push() - ctex.Translate(float64(c.width/2), float64(c.height/2)) + ctex.Translate(float64(c.Width()/2), float64(c.Height()/2)) ctex.Rotate(gg.Radians(float64(theta * (i + 1)))) ctex.Scale(sl, sl) @@ -41,14 +42,14 @@ func (s *spiralSquare) Generative(c *canva) { ctex.LineTo(-0.5, -0.5) ctex.LineTo(-0.5, 0.5) - ctex.SetLineWidth(c.opts.lineWidth) - ctex.SetColor(c.opts.lineColor) + ctex.SetLineWidth(c.Opts().LineWidth()) + ctex.SetColor(c.Opts().LineColor()) ctex.StrokePreserve() if s.randColor { - ctex.SetColor(c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))]) + ctex.SetColor(c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))]) } else { - ctex.SetColor(c.opts.foreground) + ctex.SetColor(c.Opts().Foreground()) } ctex.Fill() ctex.Pop() diff --git a/squaregrid.go b/arts/squaregrid.go similarity index 63% rename from squaregrid.go rename to arts/squaregrid.go index 5bfa2e3..21c9026 100644 --- a/squaregrid.go +++ b/arts/squaregrid.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "math/rand" ) @@ -20,19 +21,19 @@ func NewGirdSquares(step, rectSize int, decay float64) *girdSquares { } // Generative draws a grid squares image. -func (g *girdSquares) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) +func (g *girdSquares) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) - for x := 0; x < c.width; x += g.step { - for y := 0; y < c.height; y += g.step { - cl := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))] + for x := 0; x < c.Width(); x += g.step { + for y := 0; y < c.Height(); y += g.step { + cl := c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))] x0 := float64(x) y0 := float64(y) s := float64(g.rectSize) theta := rand.Intn(360) + 1 - for i := 0; i < c.opts.nIters; i++ { + for i := 0; i < c.Opts().NIters(); i++ { ctex.Push() ctex.Translate(x0+float64(g.step/2), y0+float64(g.step/2)) @@ -46,10 +47,10 @@ func (g *girdSquares) Generative(c *canva) { ctex.LineTo(-0.5, -0.5) ctex.LineTo(-0.5, 0.5) - ctex.SetLineWidth(c.opts.lineWidth) - ctex.SetColor(c.opts.lineColor) + ctex.SetLineWidth(c.Opts().LineWidth()) + ctex.SetColor(c.Opts().LineColor()) ctex.StrokePreserve() - ctex.SetRGBA255(int(cl.R), int(cl.G), int(cl.B), c.opts.alpha) + ctex.SetRGBA255(int(cl.R), int(cl.G), int(cl.B), c.Opts().Alpha()) ctex.Fill() ctex.Pop() s = s - g.decay*float64(g.rectSize) diff --git a/swirl.go b/arts/swirl.go similarity index 50% rename from swirl.go rename to arts/swirl.go index 2b47689..964abb9 100644 --- a/swirl.go +++ b/arts/swirl.go @@ -1,7 +1,8 @@ -package generativeart +package arts import ( "github.com/fogleman/gg" + "github.com/jdxyw/generativeart" "github.com/jdxyw/generativeart/common" "math" ) @@ -24,19 +25,19 @@ func NewSwirl(a, b, c, d, xaixs, yaixs float64) *swirl { } // Generative draws a swirl image. -func (s *swirl) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) - ctex.SetLineWidth(c.opts.lineWidth) +func (s *swirl) Generative(c *generativeart.Canva) { + ctex := gg.NewContextForRGBA(c.Img()) + ctex.SetLineWidth(c.Opts().LineWidth()) start := point{ x: 1.0, y: 1.0, } - cl := c.opts.foreground + cl := c.Opts().Foreground() - for i := 0; i < c.opts.nIters; i++ { + for i := 0; i < c.Opts().NIters(); i++ { next := s.swirlTransform(start) - x, y := common.ConvertCartesianToPixel(next.x, next.y, s.xaixs, s.yaixs, c.height, c.width) - c.img.Set(x, y, cl) + x, y := common.ConvertCartesianToPixel(next.x, next.y, s.xaixs, s.yaixs, c.Height(), c.Width()) + c.Img().Set(x, y, cl) start = next } @@ -51,46 +52,46 @@ func (s *swirl) swirlTransform(p point) point { } } -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 { +func (s *swirl) removeNoisy(c *generativeart.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 { + if c.Img().At(i+1, j) == c.Opts().Background() { n += 1 } - if c.img.At(i+1, j+1) == c.opts.background { + if c.Img().At(i+1, j+1) == c.Opts().Background() { n += 1 } - if c.img.At(i, j+1) == c.opts.background { + if c.Img().At(i, j+1) == c.Opts().Background() { n += 1 } - if c.img.At(i-1, j) == c.opts.background { + if c.Img().At(i-1, j) == c.Opts().Background() { n += 1 } - if c.img.At(i-1, j+1) == c.opts.background { + if c.Img().At(i-1, j+1) == c.Opts().Background() { n += 1 } - if c.img.At(i-1, j-1) == c.opts.background { + if c.Img().At(i-1, j-1) == c.Opts().Background() { n += 1 } - if c.img.At(i+1, j-1) == c.opts.background { + if c.Img().At(i+1, j-1) == c.Opts().Background() { n += 1 } - if c.img.At(i, j-1) == c.opts.background { + if c.Img().At(i, j-1) == c.Opts().Background() { n += 1 } if n > 5 { - c.img.Set(i, j, c.opts.background) + c.Img().Set(i, j, c.Opts().Background()) } } diff --git a/dotswave.go b/dotswave.go deleted file mode 100644 index de14fd8..0000000 --- a/dotswave.go +++ /dev/null @@ -1,48 +0,0 @@ -package generativeart - -import ( - "github.com/fogleman/gg" - "github.com/jdxyw/generativeart/common" - "math" - "math/rand" -) - -type dotsWave struct { - dotsN int -} - -// NewDotsWave returns a dotsWave object. -func NewDotsWave(dotsN int) *dotsWave { - return &dotsWave{ - dotsN: dotsN, - } -} - -// Generative draws a dots wave images. -func (d *dotsWave) Generative(c *canva) { - ctex := gg.NewContextForRGBA(c.img) - noise := common.NewPerlinNoise() - for i := 0; i < d.dotsN; i++ { - x := common.RandomRangeFloat64(-0.1, 1.1) * float64(c.width) - y := common.RandomRangeFloat64(-0.1, 1.1) * float64(c.height) - - num := common.RandomRangeFloat64(100, 1000) - r := rand.Float64() * float64(c.width) * 0.15 * rand.Float64() - ind := common.RandomRangeFloat64(1, 8) - - ctex.Push() - ctex.Translate(x, y) - ctex.Rotate(float64(rand.Intn(8)) * math.Pi / 4) - rand.Shuffle(len(c.opts.colorSchema), func(i, j int) { - c.opts.colorSchema[i], c.opts.colorSchema[j] = c.opts.colorSchema[j], c.opts.colorSchema[i] - }) - for j := 0.0; j < num; j += ind { - s := float64(c.width) * 0.15 * common.RandomRangeFloat64(0, common.RandomRangeFloat64(0, common.RandomRangeFloat64(0, common.RandomRangeFloat64(0, common.RandomRangeFloat64(0, common.RandomRangeFloat64(0, rand.Float64())))))) - ci := int(float64(len(c.opts.colorSchema)) * noise.Noise3D(j*0.01, x, y)) - ctex.SetColor(c.opts.colorSchema[ci]) - ctex.DrawCircle(j, r*math.Sin(j*0.05), s*2/3) - ctex.Fill() - } - ctex.Pop() - } -} diff --git a/example/example_circlegrid.go b/example/example_circlegrid.go index f8c81ef..83e08e1 100644 --- a/example/example_circlegrid.go +++ b/example/example_circlegrid.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/arts" "image/color" "math/rand" "time" @@ -22,6 +23,6 @@ func main() { c.FillBackground() c.SetColorSchema(colors) c.SetLineWidth(2.0) - c.Draw(generativeart.NewCircleGrid(4, 6)) + c.Draw(arts.NewCircleGrid(4, 6)) c.ToPNG("circlegrid.png") } diff --git a/example/example_circleline.go b/example/example_circleline.go index 828b412..1ae364e 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/arts" "github.com/jdxyw/generativeart/common" "math/rand" "time" @@ -14,6 +15,6 @@ func main() { c.SetLineWidth(1.0) c.SetLineColor(common.LightPink) c.FillBackground() - c.Draw(generativeart.NewCircleLine(0.02, 600, 1.5, 2, 2)) + c.Draw(arts.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 fed6e38..69c9f4e 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/arts" "github.com/jdxyw/generativeart/common" "math/rand" "time" @@ -16,6 +17,6 @@ func main() { c.SetAlpha(30) c.SetIterations(1000) c.FillBackground() - c.Draw(generativeart.NewCircleLoop(100)) + c.Draw(arts.NewCircleLoop(100)) c.ToPNG("circleloop.png") } diff --git a/example/example_circleloop2.go b/example/example_circleloop2.go index e0dfedf..495ca98 100644 --- a/example/example_circleloop2.go +++ b/example/example_circleloop2.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/arts" "image/color" "math/rand" "time" @@ -20,6 +21,6 @@ func main() { c.SetBackground(color.RGBA{8, 10, 20, 255}) c.FillBackground() c.SetColorSchema(colors) - c.Draw(generativeart.NewCircleLoop2(7)) + c.Draw(arts.NewCircleLoop2(7)) c.ToPNG("colorloop2.png") } diff --git a/example/example_circlemove.go b/example/example_circlemove.go index 26bef51..021278e 100644 --- a/example/example_circlemove.go +++ b/example/example_circlemove.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/arts" "github.com/jdxyw/generativeart/common" "math/rand" "time" @@ -12,6 +13,6 @@ func main() { c := generativeart.NewCanva(1200, 500) c.SetBackground(common.White) c.FillBackground() - c.Draw(generativeart.NewCircleMove(1000)) + c.Draw(arts.NewCircleMove(1000)) c.ToPNG("circlemove.png") } diff --git a/example/example_colorcircle.go b/example/example_colorcircle.go index 0737bd1..7941ca4 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/arts" "github.com/jdxyw/generativeart/common" "image/color" "math/rand" @@ -24,6 +25,6 @@ func main() { c.SetBackground(common.White) c.FillBackground() c.SetColorSchema(colors) - c.Draw(generativeart.NewColorCircle(500)) + c.Draw(arts.NewColorCircle(500)) c.ToPNG("colorcircle.png") } diff --git a/example/example_colorcircle2.go b/example/example_colorcircle2.go index d0a0f5e..2894a95 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/arts" "github.com/jdxyw/generativeart/common" "image/color" "math/rand" @@ -21,6 +22,6 @@ func main() { c.SetBackground(common.White) c.FillBackground() c.SetColorSchema(colors) - c.Draw(generativeart.NewColorCircle2(30)) + c.Draw(arts.NewColorCircle2(30)) c.ToPNG("colorcircle2.png") } diff --git a/example/example_contourline.go b/example/example_contourline.go index 9d36223..fbef933 100644 --- a/example/example_contourline.go +++ b/example/example_contourline.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/arts" "image/color" "math/rand" "time" @@ -20,6 +21,6 @@ func main() { c.SetBackground(color.RGBA{0x1a, 0x06, 0x33, 0xFF}) c.FillBackground() c.SetColorSchema(colors) - c.Draw(generativeart.NewContourLine(500)) + c.Draw(arts.NewContourLine(500)) c.ToPNG("contourline.png") } diff --git a/example/example_dotline.go b/example/example_dotline.go index 071dc35..4e61e73 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/arts" "github.com/jdxyw/generativeart/common" "image/color" "math/rand" @@ -16,6 +17,6 @@ func main() { c.SetIterations(15000) c.SetColorSchema(common.Plasma) c.FillBackground() - c.Draw(generativeart.NewDotLine(100, 20, 50, false)) + c.Draw(arts.NewDotLine(100, 20, 50, false)) c.ToPNG("dotline.png") } diff --git a/example/example_dotswave.go b/example/example_dotswave.go index c77be1b..2319378 100644 --- a/example/example_dotswave.go +++ b/example/example_dotswave.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/arts" "github.com/jdxyw/generativeart/common" "image/color" "math/rand" @@ -21,6 +22,6 @@ func main() { c.SetBackground(common.Black) c.FillBackground() c.SetColorSchema(colors) - c.Draw(generativeart.NewDotsWave(300)) + c.Draw(arts.NewDotsWave(300)) c.ToPNG("dotswave.png") } diff --git a/example/example_gridsquare.go b/example/example_gridsquare.go index a92f97e..ca50fe1 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/arts" "github.com/jdxyw/generativeart/common" "math/rand" "time" @@ -12,6 +13,6 @@ func main() { c := generativeart.NewCanva(600, 600) c.SetBackground(common.DarkPink[rand.Intn(5)]) c.SetColorSchema(common.DarkPink) - c.Draw(generativeart.NewGirdSquares(24, 10, 0.2)) + c.Draw(arts.NewGirdSquares(24, 10, 0.2)) c.ToPNG("gsquare.png") } diff --git a/example/example_janus.go b/example/example_janus.go index ba70c6f..5e68d8e 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/arts" "github.com/jdxyw/generativeart/common" "math/rand" "time" @@ -14,6 +15,6 @@ func main() { c.FillBackground() c.SetColorSchema(common.DarkRed) c.SetForeground(common.LightPink) - c.Draw(generativeart.NewJanus(10, 0.2)) + c.Draw(arts.NewJanus(10, 0.2)) c.ToPNG("janus.png") } diff --git a/example/example_julia.go b/example/example_julia.go index 89828a3..d45861a 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/arts" "github.com/jdxyw/generativeart/common" "math/rand" "time" @@ -21,6 +22,6 @@ func main() { c.SetIterations(800) c.SetColorSchema(common.Viridis) c.FillBackground() - c.Draw(generativeart.NewJulia(julia1, 40, 1.5, 1.5)) + c.Draw(arts.NewJulia(julia1, 40, 1.5, 1.5)) c.ToPNG("julia.png") } diff --git a/example/example_maze.go b/example/example_maze.go index b55f51f..637b357 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/arts" "github.com/jdxyw/generativeart/common" "math/rand" "time" @@ -14,6 +15,6 @@ func main() { c.SetLineWidth(3) c.SetLineColor(common.Orange) c.FillBackground() - c.Draw(generativeart.NewMaze(20)) + c.Draw(arts.NewMaze(20)) c.ToPNG("maze.png") } diff --git a/example/example_noiseline.go b/example/example_noiseline.go index a74b1e1..a9671a1 100644 --- a/example/example_noiseline.go +++ b/example/example_noiseline.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/arts" "image/color" "math/rand" "time" @@ -20,6 +21,6 @@ func main() { c.SetBackground(color.RGBA{0xF0, 0xFE, 0xFF, 0xFF}) c.FillBackground() c.SetColorSchema(colors) - c.Draw(generativeart.NewNoiseLine(1000)) + c.Draw(arts.NewNoiseLine(1000)) c.ToPNG("noiseline.png") } diff --git a/example/example_oceanfish.go b/example/example_oceanfish.go index 40a4aad..185c599 100644 --- a/example/example_oceanfish.go +++ b/example/example_oceanfish.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/arts" "image/color" "math/rand" "time" @@ -25,6 +26,6 @@ func main() { } c := generativeart.NewCanva(500, 500) c.SetColorSchema(colors) - c.Draw(generativeart.NewOceanFish(100, 8)) + c.Draw(arts.NewOceanFish(100, 8)) c.ToPNG("oceanfish.png") } diff --git a/example/example_pixelhole.go b/example/example_pixelhole.go index c6ee556..6b0507e 100644 --- a/example/example_pixelhole.go +++ b/example/example_pixelhole.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/arts" "github.com/jdxyw/generativeart/common" "image/color" "math/rand" @@ -22,7 +23,7 @@ func main() { c.FillBackground() c.SetColorSchema(colors) c.SetIterations(1200) - c.Draw(generativeart.NewPixelHole(60)) + c.Draw(arts.NewPixelHole(60)) c.ToPNG("pixelhole.png") } diff --git a/example/example_pointribbon.go b/example/example_pointribbon.go index bbb85e8..6e2b0f5 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/arts" "github.com/jdxyw/generativeart/common" "math/rand" "time" @@ -14,6 +15,6 @@ func main() { c.SetLineWidth(2) c.SetIterations(150000) c.FillBackground() - c.Draw(generativeart.NewPointRibbon(50)) + c.Draw(arts.NewPointRibbon(50)) c.ToPNG("pointribbon.png") } diff --git a/example/example_randcircle.go b/example/example_randcircle.go index 58bb826..7fa82e2 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/arts" "github.com/jdxyw/generativeart/common" "image/color" "math/rand" @@ -22,6 +23,6 @@ func main() { c.SetColorSchema(common.Plasma) c.SetIterations(4) c.FillBackground() - c.Draw(generativeart.NewRandCicle(30, 80, 0.2, 2, 10, 30, true)) + c.Draw(arts.NewRandCicle(30, 80, 0.2, 2, 10, 30, true)) c.ToPNG("randcircle.png") } diff --git a/example/example_randomshape.go b/example/example_randomshape.go index 0a0a5d5..777f332 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/arts" "github.com/jdxyw/generativeart/common" "image/color" "math/rand" @@ -20,6 +21,6 @@ func main() { {0x19, 0x6E, 0x94, 0xFF}, {0x35, 0x3A, 0x57, 0xFF}, }) - c.Draw(generativeart.NewRandomShape(150)) + c.Draw(arts.NewRandomShape(150)) c.ToPNG("randomshape.png") } diff --git a/example/example_silksky.go b/example/example_silksky.go index 16f98bf..92ad6c4 100644 --- a/example/example_silksky.go +++ b/example/example_silksky.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/arts" "math/rand" "time" ) @@ -10,6 +11,6 @@ func main() { rand.Seed(time.Now().Unix()) c := generativeart.NewCanva(600, 600) c.SetAlpha(10) - c.Draw(generativeart.NewSilkSky(15, 5)) + c.Draw(arts.NewSilkSky(15, 5)) c.ToPNG("silksky.png") } diff --git a/example/example_silksmoke.go b/example/example_silksmoke.go index 14b4f76..04c8f9b 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/arts" "github.com/jdxyw/generativeart/common" "math/rand" "time" @@ -17,6 +18,6 @@ func main() { c.SetColorSchema(common.Plasma) c.SetIterations(4) c.FillBackground() - c.Draw(generativeart.NewSilkSmoke(400, 20, 0.2, 2, 10, 30, false)) + c.Draw(arts.NewSilkSmoke(400, 20, 0.2, 2, 10, 30, false)) c.ToPNG("silksmoke.png") } diff --git a/example/example_solarflare.go b/example/example_solarflare.go index 0d661ba..27e269c 100644 --- a/example/example_solarflare.go +++ b/example/example_solarflare.go @@ -2,6 +2,7 @@ package main import ( "github.com/jdxyw/generativeart" + "github.com/jdxyw/generativeart/arts" "github.com/jdxyw/generativeart/common" "image/color" "math/rand" @@ -14,6 +15,6 @@ func main() { c.SetBackground(common.Black) c.FillBackground() c.SetLineColor(color.RGBA{255, 64, 8, 128}) - c.Draw(generativeart.NewSolarFlare()) + c.Draw(arts.NewSolarFlare()) c.ToPNG("solarflare.png") } diff --git a/example/example_spiralsquare.go b/example/example_spiralsquare.go index 182c15e..293279a 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/arts" "github.com/jdxyw/generativeart/common" "math/rand" "time" @@ -16,6 +17,6 @@ func main() { c.SetColorSchema(common.Plasma) c.SetForeground(common.Tomato) c.FillBackground() - c.Draw(generativeart.NewSpiralSquare(40, 400, 0.05, true)) + c.Draw(arts.NewSpiralSquare(40, 400, 0.05, true)) c.ToPNG("spiralsquare.png") } diff --git a/example/example_swirl.go b/example/example_swirl.go index f5a09ba..0b91377 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/arts" "github.com/jdxyw/generativeart/common" "image/color" "math/rand" @@ -15,6 +16,6 @@ func main() { c.FillBackground() c.SetForeground(color.RGBA{113, 3, 0, 140}) c.SetIterations(4000000) - c.Draw(generativeart.NewSwirl(0.970, -1.899, 1.381, -1.506, 2.4, 2.4)) + c.Draw(arts.NewSwirl(0.970, -1.899, 1.381, -1.506, 2.4, 2.4)) c.ToPNG("swirl.png") } diff --git a/generativeart.go b/generativeart.go index 2a86004..e0bdcf4 100644 --- a/generativeart.go +++ b/generativeart.go @@ -11,15 +11,31 @@ import ( ) type Engine interface { - Generative(c *canva) + Generative(c *Canva) } -type canva struct { +type Canva struct { height, width int img *image.RGBA opts Options } +func (c *Canva) Opts() Options { + return c.opts +} + +func (c *Canva) Img() *image.RGBA { + return c.Img() +} + +func (c *Canva) Width() int { + return c.Width() +} + +func (c *Canva) Height() int { + return c.Height() +} + type Options struct { background color.RGBA foreground color.RGBA @@ -30,9 +46,37 @@ type Options struct { alpha int } -// NewCanva returns a canva. -func NewCanva(w, h int) *canva { - return &canva{ +func (o Options) Alpha() int { + return o.alpha +} + +func (o Options) NIters() int { + return o.nIters +} + +func (o Options) ColorSchema() []color.RGBA { + return o.colorSchema +} + +func (o Options) LineWidth() float64 { + return o.lineWidth +} + +func (o Options) LineColor() color.RGBA { + return o.lineColor +} + +func (o Options) Foreground() color.RGBA { + return o.foreground +} + +func (o Options) Background() color.RGBA { + return o.background +} + +// NewCanva returns a Canva. +func NewCanva(w, h int) *Canva { + return &Canva{ height: h, width: w, img: image.NewRGBA(image.Rect(0, 0, w, h)), @@ -49,54 +93,54 @@ func NewCanva(w, h int) *canva { } } -func (c *canva) SetOptions(opts Options) { +func (c *Canva) SetOptions(opts Options) { c.opts = opts } -func (c *canva) SetBackground(rgba color.RGBA) { +func (c *Canva) SetBackground(rgba color.RGBA) { c.opts.background = rgba } -func (c *canva) SetForeground(rgba color.RGBA) { +func (c *Canva) SetForeground(rgba color.RGBA) { c.opts.foreground = rgba } -func (c *canva) SetColorSchema(rgbas []color.RGBA) { +func (c *Canva) SetColorSchema(rgbas []color.RGBA) { c.opts.colorSchema = rgbas } -func (c *canva) SetLineColor(rgba color.RGBA) { +func (c *Canva) SetLineColor(rgba color.RGBA) { c.opts.lineColor = rgba } -func (c *canva) SetLineWidth(lw float64) { +func (c *Canva) SetLineWidth(lw float64) { c.opts.lineWidth = lw } -func (c *canva) SetIterations(nIters int) { +func (c *Canva) SetIterations(nIters int) { c.opts.nIters = nIters } -func (c *canva) SetAlpha(alpha int) { +func (c *Canva) SetAlpha(alpha int) { c.opts.alpha = alpha } -func (c *canva) Draw(e Engine) { +func (c *Canva) Draw(e Engine) { e.Generative(c) } -// FillBackground fills the background of the canva. -func (c *canva) FillBackground() { - draw.Draw(c.img, c.img.Bounds(), &image.Uniform{c.opts.background}, image.ZP, draw.Src) +// FillBackground fills the background of the Canva. +func (c *Canva) FillBackground() { + draw.Draw(c.Img(), c.Img().Bounds(), &image.Uniform{c.Opts().Background()}, image.ZP, draw.Src) } // ToPng saves the image to local with PNG format. -func (c *canva) ToPNG(fpath string) error { +func (c *Canva) ToPNG(fpath string) error { f, err := os.Create(fpath) if err != nil { return err } - if err := png.Encode(f, c.img); err != nil { + if err := png.Encode(f, c.Img()); err != nil { f.Close() return err } @@ -109,12 +153,12 @@ func (c *canva) ToPNG(fpath string) error { } // ToJpeg saves the image to local with Jpeg format. -func (c *canva) ToJPEG(path string) error { +func (c *Canva) ToJPEG(path string) error { f, err := os.Create(path) if err != nil { return err } - if err := jpeg.Encode(f, c.img, nil); err != nil { + if err := jpeg.Encode(f, c.Img(), nil); err != nil { f.Close() return err } diff --git a/julia.go b/julia.go deleted file mode 100644 index 6a6fc0c..0000000 --- a/julia.go +++ /dev/null @@ -1,43 +0,0 @@ -package generativeart - -import "math/cmplx" - -// GenFunc defines a func type used by julia set. -type GenFunc func(complex128) complex128 - -type julia struct { - fn GenFunc - maxz float64 - xaixs, yaixs float64 -} - -func NewJulia(formula GenFunc, maxz, xaixs, yaixs float64) *julia { - return &julia{ - fn: formula, - maxz: maxz, - xaixs: xaixs, - yaixs: yaixs, - } -} - -// Generative draws a julia set. -func (j *julia) Generative(c *canva) { - n := len(c.opts.colorSchema) - if n > 255 { - n = 255 - } - - for i := 0; i <= c.width; i++ { - for k := 0; k <= c.height; k++ { - nit := 0 - z := complex(float64(i)/float64(c.width)*2.0*j.yaixs-j.yaixs, float64(k)/float64(c.height)*2.0*j.yaixs-j.yaixs) - - for cmplx.Abs(z) <= j.maxz && nit < c.opts.nIters { - z = j.fn(z) - nit += 1 - } - idx := uint8(nit*255/c.opts.nIters) % uint8(n) - c.img.Set(i, k, c.opts.colorSchema[idx]) - } - } -}