minor refactor and update the readme

This commit is contained in:
Yongwei Xing 2021-03-04 10:46:41 +08:00
parent b78c540dc8
commit 4cf80677c7
15 changed files with 105 additions and 106 deletions

View file

@ -20,6 +20,8 @@ For these kinds of art, the package provides as many as parameters to control th
## Install ## Install
The go version I used is go 1.16.
```bash ```bash
go get github.com/jdxyw/generativeart go get github.com/jdxyw/generativeart
``` ```
@ -27,15 +29,32 @@ go get github.com/jdxyw/generativeart
## Art Type ## Art Type
```go ```go
NewCircleLine(step float64, lineNum int, radius float64) NewCircleLine(step float64, lineNum int, radius, xaixs, yaixs float64)
NewCircleLoop(radius float64) NewCircleLoop(radius float64)
NewMaze() NewMaze(step int)
NewRandCicle(mc, msp int, minStep, maxStep, minr, maxr float64, isRandColor bool) NewRandCicle(mc, msp int, minStep, maxStep, minr, maxr float64, isRandColor bool)
NewSilkSky(circleNum int, sunRadius float64) NewSilkSky(circleNum int, sunRadius float64)
NewSilkSmoke(mc, msp int, minStep, maxStep, minRadius, maxRadius float64, isRandColor bool) NewSilkSmoke(mc, msp int, minStep, maxStep, minRadius, maxRadius float64, isRandColor bool)
NewSpiralSquare(squareNum int, rectSide, decay float64, randColor bool) NewSpiralSquare(squareNum int, rectSide, decay float64, randColor bool)
``` ```
## General Options
```go
type Options struct {
background color.RGBA
foreground color.RGBA
lineColor color.RGBA
lineWidth float64
colorSchema []color.RGBA
nIters int
alpha int
}
```
The `Options` is a global option for the whole `canva`. It includes those general parameters used by different kinds of types, such as `background`, `lineColor`, and `colorScheme`.
For those parameters specified for different kinds of art type, they have their own `struct`.
## Usage and example ## Usage and example
### Silk Smoke ### Silk Smoke
@ -43,7 +62,7 @@ NewSpiralSquare(squareNum int, rectSide, decay float64, randColor bool)
```go ```go
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 2, 2) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.Black) c.SetBackground(generativeart.Black)
c.SetLineWidth(1.0) c.SetLineWidth(1.0)
c.SetLineColor(generativeart.MediumAquamarine) c.SetLineColor(generativeart.MediumAquamarine)
@ -63,11 +82,11 @@ func main() {
```go ```go
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 2, 2) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.MistyRose) c.SetBackground(generativeart.MistyRose)
c.SetLineWidth(10) c.SetLineWidth(10)
c.SetLineColor(generativeart.Orange) c.SetLineColor(generativeart.Orange)
c.SetColorSchema(generativeart.Viridis) c.SetColorSchema(generativeart.Plasma)
c.SetForeground(generativeart.Tomato) c.SetForeground(generativeart.Tomato)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewSpiralSquare(40, 400, 0.05, true)) c.Draw(generativeart.NewSpiralSquare(40, 400, 0.05, true))
@ -82,7 +101,7 @@ func main() {
```go ```go
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 2, 2) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.Black) c.SetBackground(generativeart.Black)
c.SetLineWidth(1) c.SetLineWidth(1)
c.SetLineColor(generativeart.Orange) c.SetLineColor(generativeart.Orange)
@ -101,7 +120,6 @@ func main() {
```go ```go
func julia1(z complex128) complex128 { func julia1(z complex128) complex128 {
c := complex(-0.1, 0.651) c := complex(-0.1, 0.651)
z = z*z + c z = z*z + c
return z return z
@ -109,11 +127,11 @@ func julia1(z complex128) complex128 {
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 1.5, 1.5) c := generativeart.NewCanva(500, 500)
c.SetIterations(800) c.SetIterations(800)
c.SetColorSchema(generativeart.Viridis) c.SetColorSchema(generativeart.Viridis)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewJulia(julia1, 40)) c.Draw(generativeart.NewJulia(julia1, 40, 1.5, 1.5))
c.ToPNG("julia.png") c.ToPNG("julia.png")
} }
``` ```
@ -125,12 +143,12 @@ func main() {
```go ```go
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600, 2, 2) c := generativeart.NewCanva(600, 600)
c.SetBackground(generativeart.Tan) c.SetBackground(generativeart.Tan)
c.SetLineWidth(1.0) c.SetLineWidth(1.0)
c.SetLineColor(generativeart.LightPink) c.SetLineColor(generativeart.LightPink)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewCircleLine(0.02, 600, 1.5)) c.Draw(generativeart.NewCircleLine(0.02, 600, 1.5, 2, 2))
c.ToPNG("circleline.png") c.ToPNG("circleline.png")
} }
``` ```
@ -142,7 +160,7 @@ func main() {
```go ```go
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600, 1, 1) c := generativeart.NewCanva(600, 600)
c.SetAlpha(10) c.SetAlpha(10)
c.Draw(generativeart.NewSilkSky(15, 5)) c.Draw(generativeart.NewSilkSky(15, 5))
c.ToPNG("silksky.png") c.ToPNG("silksky.png")
@ -156,12 +174,12 @@ func main() {
```go ```go
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600, 2, 2) c := generativeart.NewCanva(600, 600)
c.SetBackground(generativeart.Azure) c.SetBackground(generativeart.Azure)
c.SetLineWidth(3) c.SetLineWidth(3)
c.SetLineColor(generativeart.Orange) c.SetLineColor(generativeart.Orange)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewMaze()) c.Draw(generativeart.NewMaze(20))
c.ToPNG("maze.png") c.ToPNG("maze.png")
} }
``` ```
@ -173,7 +191,7 @@ func main() {
```go ```go
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 2, 2) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.MistyRose) c.SetBackground(generativeart.MistyRose)
c.SetLineWidth(1.0) c.SetLineWidth(1.0)
c.SetLineColor(color.RGBA{ c.SetLineColor(color.RGBA{

View file

@ -11,17 +11,20 @@ type point struct {
} }
type circleLine struct { type circleLine struct {
step float64 step float64
lineNum int lineNum int
radius float64 radius float64
xaixs, yaixs float64
} }
// NewCircleLine returns a circleLine object. // NewCircleLine returns a circleLine object.
func NewCircleLine(step float64, lineNum int, radius float64) *circleLine { func NewCircleLine(step float64, lineNum int, radius, xaixs, yaixs float64) *circleLine {
return &circleLine{ return &circleLine{
step: step, step: step,
lineNum: lineNum, lineNum: lineNum,
radius: radius, radius: radius,
xaixs: xaixs,
yaixs: yaixs,
} }
} }
@ -34,7 +37,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, c.xaixs, c.yaixs, c.width, c.height) xi, yi := 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

@ -8,11 +8,11 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600, 2, 2) c := generativeart.NewCanva(600, 600)
c.SetBackground(generativeart.Tan) c.SetBackground(generativeart.Tan)
c.SetLineWidth(1.0) c.SetLineWidth(1.0)
c.SetLineColor(generativeart.LightPink) c.SetLineColor(generativeart.LightPink)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewCircleLine(0.02, 600, 1.5)) c.Draw(generativeart.NewCircleLine(0.02, 600, 1.5, 2, 2))
c.ToPNG("circleline.png") c.ToPNG("circleline.png")
} }

View file

@ -8,7 +8,7 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 2, 2) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.Black) c.SetBackground(generativeart.Black)
c.SetLineWidth(1) c.SetLineWidth(1)
c.SetLineColor(generativeart.Orange) c.SetLineColor(generativeart.Orange)

View file

@ -8,9 +8,9 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600, 1, 1) c := generativeart.NewCanva(600, 600)
c.SetBackground(generativeart.DarkPink[rand.Intn(5)]) c.SetBackground(generativeart.DarkPink[rand.Intn(5)])
c.SetColorSchema(generativeart.DarkPink) c.SetColorSchema(generativeart.DarkPink)
c.Draw(generativeart.NewGirdSquares()) c.Draw(generativeart.NewGirdSquares(24, 10, 0.2))
c.ToPNG("gsquare.png") c.ToPNG("gsquare.png")
} }

View file

@ -16,10 +16,10 @@ func julia1(z complex128) complex128 {
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 1.5, 1.5) c := generativeart.NewCanva(500, 500)
c.SetIterations(800) c.SetIterations(800)
c.SetColorSchema(generativeart.Viridis) c.SetColorSchema(generativeart.Viridis)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewJulia(julia1, 40)) c.Draw(generativeart.NewJulia(julia1, 40, 1.5, 1.5))
c.ToPNG("julia.png") c.ToPNG("julia.png")
} }

View file

@ -8,11 +8,11 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600, 2, 2) c := generativeart.NewCanva(600, 600)
c.SetBackground(generativeart.Azure) c.SetBackground(generativeart.Azure)
c.SetLineWidth(3) c.SetLineWidth(3)
c.SetLineColor(generativeart.Orange) c.SetLineColor(generativeart.Orange)
c.FillBackground() c.FillBackground()
c.Draw(generativeart.NewMaze()) c.Draw(generativeart.NewMaze(20))
c.ToPNG("maze.png") c.ToPNG("maze.png")
} }

View file

@ -9,7 +9,7 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 2, 2) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.MistyRose) c.SetBackground(generativeart.MistyRose)
c.SetLineWidth(1.0) c.SetLineWidth(1.0)
c.SetLineColor(color.RGBA{ c.SetLineColor(color.RGBA{

View file

@ -8,7 +8,7 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600, 1, 1) c := generativeart.NewCanva(600, 600)
c.SetAlpha(10) c.SetAlpha(10)
c.Draw(generativeart.NewSilkSky(15, 5)) c.Draw(generativeart.NewSilkSky(15, 5))
c.ToPNG("silksky.png") c.ToPNG("silksky.png")

View file

@ -8,7 +8,7 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 2, 2) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.Black) c.SetBackground(generativeart.Black)
c.SetLineWidth(1.0) c.SetLineWidth(1.0)
c.SetLineColor(generativeart.MediumAquamarine) c.SetLineColor(generativeart.MediumAquamarine)

View file

@ -8,7 +8,7 @@ import (
func main() { func main() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 2, 2) c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.MistyRose) c.SetBackground(generativeart.MistyRose)
c.SetLineWidth(10) c.SetLineWidth(10)
c.SetLineColor(generativeart.Orange) c.SetLineColor(generativeart.Orange)

View file

@ -15,48 +15,35 @@ type Engine interface {
type canva struct { type canva struct {
height, width int height, width int
xaixs, yaixs float64
img *image.RGBA img *image.RGBA
opts Options opts Options
} }
type Options struct { type Options struct {
background color.RGBA background color.RGBA
foreground color.RGBA foreground color.RGBA
lineColor color.RGBA lineColor color.RGBA
lineWidth float64 lineWidth float64
colorSchema []color.RGBA colorSchema []color.RGBA
isPolarCoodinate bool nIters int
step int alpha int
nIters int
alpha int
rectLenSide int
radius float64
decay float64
} }
// NewCanva returns a canva. // NewCanva returns a canva.
func NewCanva(h, w int, x, y float64) *canva { func NewCanva(h, w int) *canva {
return &canva{ return &canva{
height: h, height: h,
width: w, width: w,
xaixs: x,
yaixs: y,
img: image.NewRGBA(image.Rect(0, 0, h, w)), img: image.NewRGBA(image.Rect(0, 0, h, w)),
// Set some defaults value // Set some defaults value
opts: Options{ opts: Options{
background: Azure, background: Azure,
foreground: MistyRose, foreground: MistyRose,
lineColor: Tomato, lineColor: Tomato,
lineWidth: 3, lineWidth: 3,
colorSchema: Plasma, colorSchema: Plasma,
isPolarCoodinate: false, nIters: 20,
step: 24, alpha: 255,
nIters: 20,
alpha: 30,
rectLenSide: 10,
radius: 1.0,
decay: 0.2,
}, },
} }
} }
@ -85,14 +72,6 @@ func (c *canva) SetLineWidth(lw float64) {
c.opts.lineWidth = lw c.opts.lineWidth = lw
} }
func (c *canva) SetPolarCoodinate() {
c.opts.isPolarCoodinate = true
}
func (c *canva) SetStep(step int) {
c.opts.step = step
}
func (c *canva) SetIterations(nIters int) { func (c *canva) SetIterations(nIters int) {
c.opts.nIters = nIters c.opts.nIters = nIters
} }
@ -101,18 +80,6 @@ func (c *canva) SetAlpha(alpha int) {
c.opts.alpha = alpha c.opts.alpha = alpha
} }
func (c *canva) SetRectLenSide(l int) {
c.opts.rectLenSide = l
}
func (c *canva) SetRadius(r float64) {
c.opts.radius = r
}
func (c *canva) SetDecay(d float64) {
c.opts.decay = d
}
func (c *canva) Draw(e Engine) { func (c *canva) Draw(e Engine) {
e.Generative(c) e.Generative(c)
} }

View file

@ -6,14 +6,17 @@ import "math/cmplx"
type GenFunc func(complex128) complex128 type GenFunc func(complex128) complex128
type julia struct { type julia struct {
fn GenFunc fn GenFunc
maxz float64 maxz float64
xaixs, yaixs float64
} }
func NewJulia(formula GenFunc, maxz float64) *julia { func NewJulia(formula GenFunc, maxz, xaixs, yaixs float64) *julia {
return &julia{ return &julia{
fn: formula, fn: formula,
maxz: maxz, maxz: maxz,
xaixs: xaixs,
yaixs: yaixs,
} }
} }
@ -27,7 +30,7 @@ func (j *julia) Generative(c *canva) {
for i := 0; i <= c.width; i++ { for i := 0; i <= c.width; i++ {
for k := 0; k <= c.height; k++ { for k := 0; k <= c.height; k++ {
nit := 0 nit := 0
z := complex(float64(i)/float64(c.width)*2.0*c.yaixs-c.yaixs, float64(k)/float64(c.height)*2.0*c.yaixs-c.yaixs) 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 { for cmplx.Abs(z) <= j.maxz && nit < c.opts.nIters {
z = j.fn(z) z = j.fn(z)

19
maze.go
View file

@ -6,11 +6,15 @@ import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
) )
type maze struct{} type maze struct {
step int
}
// NewMaze returns a maze generator. // NewMaze returns a maze generator.
func NewMaze() *maze { func NewMaze(step int) *maze {
return &maze{} return &maze{
step: step,
}
} }
// Generative draws a random maze image. // Generative draws a random maze image.
@ -18,13 +22,12 @@ func (m *maze) Generative(c *canva) {
ctex := gg.NewContextForRGBA(c.img) ctex := gg.NewContextForRGBA(c.img)
ctex.SetColor(c.opts.lineColor) ctex.SetColor(c.opts.lineColor)
ctex.SetLineWidth(c.opts.lineWidth) ctex.SetLineWidth(c.opts.lineWidth)
step := c.opts.step for x := 0; x < c.width; x += m.step {
for x := 0; x < c.width; x += step { for y := 0; y < c.height; y += m.step {
for y := 0; y < c.height; y += step {
if rand.Float32() > 0.5 { if rand.Float32() > 0.5 {
ctex.DrawLine(float64(x), float64(y), float64(x+step), float64(y+step)) ctex.DrawLine(float64(x), float64(y), float64(x+m.step), float64(y+m.step))
} else { } else {
ctex.DrawLine(float64(x+step), float64(y), float64(x), float64(y+step)) ctex.DrawLine(float64(x+m.step), float64(y), float64(x), float64(y+m.step))
} }
ctex.Stroke() ctex.Stroke()
} }

View file

@ -5,32 +5,37 @@ import (
"math/rand" "math/rand"
) )
type girdSquares struct{} type girdSquares struct {
step, rectSize int
decay float64
}
// NewGirdSquares returns a grid squares generator. // NewGirdSquares returns a grid squares generator.
func NewGirdSquares() *girdSquares { func NewGirdSquares(step, rectSize int, decay float64) *girdSquares {
return &girdSquares{} return &girdSquares{
step: step,
rectSize: rectSize,
decay: decay,
}
} }
// Generative draws a grid squares image. // Generative draws a grid squares image.
func (g *girdSquares) Generative(c *canva) { func (g *girdSquares) Generative(c *canva) {
ctex := gg.NewContextForRGBA(c.img) ctex := gg.NewContextForRGBA(c.img)
step := c.opts.step
rectSize := c.opts.rectLenSide
for x := 0; x < c.width; x += step { for x := 0; x < c.width; x += g.step {
for y := 0; y < c.height; y += step { for y := 0; y < c.height; y += g.step {
cl := c.opts.colorSchema[rand.Intn(255)] cl := c.opts.colorSchema[rand.Intn(len(c.opts.colorSchema))]
x0 := float64(x) x0 := float64(x)
y0 := float64(y) y0 := float64(y)
s := float64(rectSize) s := float64(g.rectSize)
theta := rand.Intn(360) + 1 theta := rand.Intn(360) + 1
for i := 0; i < c.opts.nIters; i++ { for i := 0; i < c.opts.nIters; i++ {
ctex.Push() ctex.Push()
ctex.Translate(x0+float64(step/2), y0+float64(step/2)) ctex.Translate(x0+float64(g.step/2), y0+float64(g.step/2))
ctex.Rotate(gg.Radians(float64(theta * i))) ctex.Rotate(gg.Radians(float64(theta * i)))
ctex.Scale(s, s) ctex.Scale(s, s)
@ -47,7 +52,7 @@ func (g *girdSquares) Generative(c *canva) {
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.Fill()
ctex.Pop() ctex.Pop()
s = s - c.opts.decay*float64(rectSize) s = s - g.decay*float64(g.rectSize)
} }
} }
} }