move the util file to the common folder; add contour line

This commit is contained in:
Yongwei Xing 2021-03-09 13:10:53 +08:00
parent f23d235c06
commit c25daba2ed
17 changed files with 124 additions and 39 deletions

View file

@ -2,6 +2,7 @@ package generativeart
import ( import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
"github.com/jdxyw/generativeart/common"
"image/color" "image/color"
"math" "math"
"math/rand" "math/rand"
@ -27,7 +28,7 @@ func (cg *circleGrid) Generative(c *canva) {
ctex.Scale(0.9, 0.9) 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 := RandomRangeInt(cg.circleNumMin, cg.circleNumMax) 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 i := 0; i < seg; i++ {
@ -35,9 +36,9 @@ func (cg *circleGrid) Generative(c *canva) {
x := float64(i)*w + w/2 x := float64(i)*w + w/2
y := float64(j)*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*RandomRangeFloat64(0.1, 0.5)) ctex.DrawCircle(x, y, w/2*common.RandomRangeFloat64(0.1, 0.5))
ctex.Fill() 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.DrawCircle(0, 0, r)
ctex.Stroke() ctex.Stroke()
case 1: case 1:
n := RandomRangeInt(1, 4) * 2 n := common.RandomRangeInt(1, 4) * 2
ctex.DrawCircle(0, 0, r) ctex.DrawCircle(0, 0, r)
ctex.Stroke() ctex.Stroke()
for i := 0; i < n; i++ { 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() ctex.Fill()
} }
case 2: case 2:
n := RandomRangeInt(8, 20) n := common.RandomRangeInt(8, 20)
theta := math.Pi * 0.5 * float64(RandomRangeInt(1, 5)) theta := math.Pi * 0.5 * float64(common.RandomRangeInt(1, 5))
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
d := float64(i) / float64(n) d := float64(i) / float64(n)
if d > r*0.1 { if d > r*0.1 {
@ -77,7 +78,7 @@ func (cg *circleGrid) draw(ctex *gg.Context, c *canva, x, y, r float64) {
ctex.Fill() ctex.Fill()
} }
case 3: case 3:
n := RandomRangeInt(5, 20) n := common.RandomRangeInt(5, 20)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
ctex.Rotate(math.Pi * 2 / float64(n)) ctex.Rotate(math.Pi * 2 / float64(n))
ctex.DrawLine(r/2, 0, (r*2/3)-(r*0.05), 0) ctex.DrawLine(r/2, 0, (r*2/3)-(r*0.05), 0)

View file

@ -2,6 +2,7 @@ package generativeart
import ( import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
"github.com/jdxyw/generativeart/common"
"math" "math"
"math/rand" "math/rand"
) )
@ -37,7 +38,7 @@ func (cl *circleLine) Generative(c *canva) {
for theta := -math.Pi; theta <= math.Pi; theta += cl.step { for theta := -math.Pi; theta <= math.Pi; theta += cl.step {
x := cl.radius * math.Cos(theta) x := cl.radius * math.Cos(theta)
y := cl.radius * math.Sin(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{ points = append(points, point{
x: float64(xi), x: float64(xi),
y: float64(yi), y: float64(yi),

View file

@ -2,6 +2,7 @@ package generativeart
import ( import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
"github.com/jdxyw/generativeart/common"
"math" "math"
"math/rand" "math/rand"
) )
@ -22,9 +23,9 @@ func (cc *colorCircle) Generative(c *canva) {
for i := 0; i < cc.circleNum; i++ { for i := 0; i < cc.circleNum; i++ {
rnd := rand.Intn(3) rnd := rand.Intn(3)
x := RandomRangeFloat64(-0.1, 1.1) * float64(c.width) x := common.RandomRangeFloat64(-0.1, 1.1) * float64(c.width)
y := RandomRangeFloat64(-0.1, 1.1) * float64(c.height) y := common.RandomRangeFloat64(-0.1, 1.1) * float64(c.height)
s := RandomRangeFloat64(0, RandomRangeFloat64(0, float64(c.width/2))) + 10 s := common.RandomRangeFloat64(0, common.RandomRangeFloat64(0, float64(c.width/2))) + 10
if rnd == 2 { if rnd == 2 {
rnd = rand.Intn(3) rnd = rand.Intn(3)
} }
@ -32,9 +33,9 @@ func (cc *colorCircle) Generative(c *canva) {
case 0: case 0:
cc.drawCircleV1(ctex, c, x, y, s) cc.drawCircleV1(ctex, c, x, y, s)
case 1: 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.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() ctex.Stroke()
case 2: case 2:
cc.drawCircleV2(ctex, c, x, y, s) 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) { func (cc *colorCircle) drawCircleV1(ctex *gg.Context, c *canva, x, y, s float64) {
n := RandomRangeInt(4, 30) n := common.RandomRangeInt(4, 30)
cs := RandomRangeFloat64(2, 8) 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.Push()
ctex.Translate(x, y) 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) { func (cc *colorCircle) drawCircleV2(ctex *gg.Context, c *canva, x, y, s float64) {
cl := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))] cl := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))]
ctex.SetLineWidth(1.0) 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++ { for j := 0.0001; j < sx; j++ {
dd := s + j*2.0 dd := s + j*2.0
alpha := int(255 * sx / j) 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) ctex.SetColor(cl)
for i := 0; i < 200; i++ { 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) xx := x + dd*0.3*math.Cos(theta)
yy := y + dd*0.3*math.Sin(theta) yy := y + dd*0.3*math.Sin(theta)
//ctex.DrawLine(xx, yy, xx, yy) //ctex.DrawLine(xx, yy, xx, yy)

View file

@ -2,6 +2,7 @@ package generativeart
import ( import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
"github.com/jdxyw/generativeart/common"
"math" "math"
"math/rand" "math/rand"
) )
@ -22,11 +23,11 @@ func (cc *colorCircle2) Generative(c *canva) {
ctex := gg.NewContextForRGBA(c.img) ctex := gg.NewContextForRGBA(c.img)
for i := 0; i < cc.circleNum; i++ { for i := 0; i < cc.circleNum; i++ {
x := RandomRangeFloat64(0, float64(c.width)) x := common.RandomRangeFloat64(0, float64(c.width))
y := RandomRangeFloat64(0, float64(c.height)) y := common.RandomRangeFloat64(0, float64(c.height))
r1 := RandomRangeFloat64(50.0, float64(c.width)/4) r1 := common.RandomRangeFloat64(50.0, float64(c.width)/4)
r2 := RandomRangeFloat64(10.0, float64(c.width)/3) r2 := common.RandomRangeFloat64(10.0, float64(c.width)/3)
cc.circle(ctex, c, x, y, r1, r2) cc.circle(ctex, c, x, y, r1, r2)
if rand.Float64() < 0.3 { 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) ctex.SetColor(col)
for i := 0; i < 150; i++ { 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) xx := x + dd*0.5*math.Cos(theta)
yy := y + dd*0.5*math.Sin(theta) yy := y + dd*0.5*math.Sin(theta)
ctex.DrawPoint(xx, yy, 0.51) ctex.DrawPoint(xx, yy, 0.51)

View file

@ -1,4 +1,4 @@
package generativeart package common
import ( import (
"image/color" "image/color"

View file

@ -1,4 +1,4 @@
package generativeart package common
import ( import (
"math" "math"

46
contourline.go Normal file
View file

@ -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<cl.lineNum;i++ {
cl := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))]
for j :=0; j<5;j++ {
x := rand.Float64()*float64(c.width)
y := rand.Float64()*float64(c.height)
theta := noise.Noise2D(x/800.0, y/800.0) * math.Pi*2*800
x += math.Cos(theta)*0.4
y += math.Sin(theta)*0.4
ctex.SetColor(cl)
ctex.DrawEllipse(x, y, 1, 1)
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)
}
}
}
}

View file

@ -2,6 +2,7 @@ package generativeart
import ( import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
"github.com/jdxyw/generativeart/common"
"math/rand" "math/rand"
) )
@ -35,13 +36,13 @@ func (d *dotLine) Generative(c *canva) {
if d.randColor { 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 { } 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++ { for j := 0; j < n; j++ {
newx := oldx + dir[rand.Intn(2)] newx := oldx + dir[rand.Intn(2)]
newy := oldy + 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 newx = oldx
newy = oldy newy = oldy
} }

View file

@ -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")
}

1
go.mod
View file

@ -3,6 +3,7 @@ module github.com/jdxyw/generativeart
go 1.16 go 1.16
require ( require (
github.com/aquilax/go-perlin v1.0.0
github.com/fogleman/gg v1.3.0 github.com/fogleman/gg v1.3.0
github.com/llgcode/draw2d v0.0.0-20200930101115-bfaf5d914d1e github.com/llgcode/draw2d v0.0.0-20200930101115-bfaf5d914d1e
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb // indirect golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb // indirect

2
go.sum
View file

@ -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 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= 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= github.com/go-gl/gl v0.0.0-20180407155706-68e253793080/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk=

View file

@ -2,6 +2,7 @@ package generativeart
import ( import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
"github.com/jdxyw/generativeart/common"
"math" "math"
) )
@ -33,11 +34,11 @@ func (j *janus) Generative(c *canva) {
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 += 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 x1, y1 := math.Cos(theta)*r, math.Sin(theta)*r
x2, y2 := -x1, -y1 x2, y2 := -x1, -y1
noise := RandomRangeFloat64(-math.Abs(y1), math.Abs(y1)) noise := common.RandomRangeFloat64(-math.Abs(y1), math.Abs(y1))
y1 += noise y1 += noise
y2 += noise y2 += noise

View file

@ -2,6 +2,7 @@ package generativeart
import ( import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
"github.com/jdxyw/generativeart/common"
"math" "math"
"math/rand" "math/rand"
) )
@ -109,7 +110,7 @@ func (r *randCircle) Generative(c *canva) {
continue 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 { if distance <= c1.radius+c2.radius {
cx := (c1.x + c2.x) / 2 cx := (c1.x + c2.x) / 2

View file

@ -2,6 +2,7 @@ package generativeart
import ( import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
"github.com/jdxyw/generativeart/common"
"math" "math"
"math/rand" "math/rand"
) )
@ -21,15 +22,15 @@ func (r *randomShape) Generative(c *canva) {
ctex := gg.NewContextForRGBA(c.img) 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(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)) ctex.Translate(-float64(c.width/2), -float64(c.height/2))
for i := 0; i < r.shapeNum; i++ { for i := 0; i < r.shapeNum; i++ {
x := RandomGaussian(0.5, 0.2) * float64(c.width) x := common.RandomGaussian(0.5, 0.2) * float64(c.width)
y := RandomGaussian(0.5, 0.2) * float64(c.height) y := common.RandomGaussian(0.5, 0.2) * float64(c.height)
w := RandomRangeFloat64(0, float64(c.width)/3)*RandomRangeFloat64(0, rand.Float64()) + 5.0 w := common.RandomRangeFloat64(0, float64(c.width)/3)*common.RandomRangeFloat64(0, rand.Float64()) + 5.0
h := w + RandomRangeFloat64(-1, 1)*3.0 h := w + common.RandomRangeFloat64(-1, 1)*3.0
rnd := rand.Intn(4) rnd := rand.Intn(4)
theta := math.Pi * 2.0 * float64(rand.Intn(4)) / 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) ctex.DrawRectangle(0, 0, w, h)
} }
case 3: case 3:
ctex.DrawRectangle(0, 0, w*2, RandomRangeFloat64(2, 10)) ctex.DrawRectangle(0, 0, w*2, common.RandomRangeFloat64(2, 10))
} }
ctex.Fill() ctex.Fill()
ctex.Pop() ctex.Pop()

View file

@ -2,6 +2,7 @@ package generativeart
import ( import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
"github.com/jdxyw/generativeart/common"
"math/rand" "math/rand"
) )
@ -30,7 +31,7 @@ func (s *silkSky) Generative(c *canva) {
for i := 0; i < s.circleNum; i++ { for i := 0; i < s.circleNum; i++ {
for j := 0; j < s.circleNum; j++ { for j := 0; j < s.circleNum; j++ {
hsv := HSV{ hsv := common.HSV{
H: s.circleNum + j, H: s.circleNum + j,
S: i + 50, S: i + 50,
V: 70, V: 70,
@ -39,7 +40,7 @@ func (s *silkSky) Generative(c *canva) {
xn := (float64(i) + 0.5) * float64(c.width) / float64(s.circleNum) xn := (float64(i) + 0.5) * float64(c.width) / float64(s.circleNum)
yn := (float64(j) + 0.5) * float64(c.height) / 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) 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.DrawEllipse(xn, yn, r-s.sunRadius/2, r-s.sunRadius/2)
ctex.Fill() ctex.Fill()
} }

View file

@ -2,6 +2,7 @@ package generativeart
import ( import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
"github.com/jdxyw/generativeart/common"
"math/rand" "math/rand"
) )
@ -51,7 +52,7 @@ func (s *sileSmoke) Generative(c *canva) {
continue 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 { if distance <= c1.radius+c2.radius {
cx := (c1.x + c2.x) / 2 cx := (c1.x + c2.x) / 2

View file

@ -2,6 +2,7 @@ package generativeart
import ( import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
"github.com/jdxyw/generativeart/common"
"math" "math"
) )
@ -34,7 +35,7 @@ func (s *swirl) Generative(c *canva) {
for i := 0; i < c.opts.nIters; i++ { for i := 0; i < c.opts.nIters; i++ {
next := s.swirlTransform(start) 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) c.img.Set(x, y, cl)
start = next start = next
} }