From 05f31aca8eda86d2ebc11b1adfa363271f396690 Mon Sep 17 00:00:00 2001 From: Yongwei Xing Date: Tue, 2 Mar 2021 17:11:26 +0800 Subject: [PATCH] add silk smoke --- example/example_silksmoke.go | 26 +++++++++++++ randcircle.go | 12 +++--- silksmoke.go | 75 ++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 example/example_silksmoke.go create mode 100644 silksmoke.go diff --git a/example/example_silksmoke.go b/example/example_silksmoke.go new file mode 100644 index 0000000..46edc02 --- /dev/null +++ b/example/example_silksmoke.go @@ -0,0 +1,26 @@ +package main + +import ( + "generativeart" + "image/color" + "math/rand" + "time" +) + +func main() { + rand.Seed(time.Now().Unix()) + c := generativeart.NewCanva(500, 500, 2, 2) + c.SetBackground(generativeart.Black) + c.SetLineWidth(1.0) + c.SetLineColor(color.RGBA{ + R: 255, + G: 255, + B: 255, + A: 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") +} diff --git a/randcircle.go b/randcircle.go index cb65278..9dfc627 100644 --- a/randcircle.go +++ b/randcircle.go @@ -34,15 +34,15 @@ func NewRandCicle(mc, msp int, minStep, maxStep, minr, maxr float64, isRandColor } } -func (r *randCircle) newCircleSlice(cn, w, h int) []circle { +func newCircleSlice(cn, w, h int, minStep, maxStep, minRadius, maxRadius float64) []circle { var circles []circle for i := 0; i < cn; i++ { x := rand.Intn(w) + 1 y := rand.Intn(h) + 1 - radius := float64(rand.Intn(int(r.minRadius))) + r.maxRadius - r.minRadius + radius := float64(rand.Intn(int(minRadius))) + maxRadius - minRadius angle := rand.Float64() * math.Pi * 2.0 - step := r.minSteps + rand.Float64()*(r.maxSteps-r.minSteps) + step := minStep + rand.Float64()*(maxStep-minStep) circles = append(circles, circle{ x: float64(x), y: float64(y), @@ -55,7 +55,7 @@ func (r *randCircle) newCircleSlice(cn, w, h int) []circle { return circles } -func (r *randCircle) circleSliceUpdate(cs []circle, w, h int) []circle { +func circleSliceUpdate(cs []circle, w, h int) []circle { var circles []circle for _, c := range cs { @@ -94,7 +94,7 @@ func (r *randCircle) Generative(c *canva) { for j := 0; j < c.opts.nIters; j++ { cn := rand.Intn(r.maxCircle) + int(r.maxCircle/3) - circles := r.newCircleSlice(cn, c.width, c.height) + 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 { @@ -123,7 +123,7 @@ func (r *randCircle) Generative(c *canva) { } } - circles = r.circleSliceUpdate(circles, c.width, c.height) + circles = circleSliceUpdate(circles, c.width, c.height) } } } diff --git a/silksmoke.go b/silksmoke.go new file mode 100644 index 0000000..c13c0ba --- /dev/null +++ b/silksmoke.go @@ -0,0 +1,75 @@ +package generativeart + +import ( + "github.com/fogleman/gg" + "math/rand" +) + +type sileSmoke struct { + maxCircle int + maxStepsPerCircle int + minSteps float64 + maxSteps float64 + minRadius float64 + maxRadius float64 + isRandColor bool +} + +func NewSilkSmoke(mc, msp int, minStep, maxStep, minRadius, maxRadius float64, isRandColor bool) *sileSmoke { + return &sileSmoke{ + maxCircle: mc, + maxStepsPerCircle: msp, + minSteps: minStep, + maxSteps: maxStep, + minRadius: minRadius, + maxRadius: maxRadius, + isRandColor: isRandColor, + } +} + +// Generative draws a silk smoke image. +func (s *sileSmoke) Generative(c *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) + + for i :=0; i