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
The go version I used is go 1.16.
```bash
go get github.com/jdxyw/generativeart
```
@ -27,15 +29,32 @@ go get github.com/jdxyw/generativeart
## Art Type
```go
NewCircleLine(step float64, lineNum int, radius float64)
NewCircleLine(step float64, lineNum int, radius, xaixs, yaixs float64)
NewCircleLoop(radius float64)
NewMaze()
NewMaze(step int)
NewRandCicle(mc, msp int, minStep, maxStep, minr, maxr float64, isRandColor bool)
NewSilkSky(circleNum int, sunRadius float64)
NewSilkSmoke(mc, msp int, minStep, maxStep, minRadius, maxRadius float64, isRandColor 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
### Silk Smoke
@ -43,7 +62,7 @@ NewSpiralSquare(squareNum int, rectSide, decay float64, randColor bool)
```go
func main() {
rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 2, 2)
c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.Black)
c.SetLineWidth(1.0)
c.SetLineColor(generativeart.MediumAquamarine)
@ -63,11 +82,11 @@ func main() {
```go
func main() {
rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 2, 2)
c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.MistyRose)
c.SetLineWidth(10)
c.SetLineColor(generativeart.Orange)
c.SetColorSchema(generativeart.Viridis)
c.SetColorSchema(generativeart.Plasma)
c.SetForeground(generativeart.Tomato)
c.FillBackground()
c.Draw(generativeart.NewSpiralSquare(40, 400, 0.05, true))
@ -82,7 +101,7 @@ func main() {
```go
func main() {
rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 2, 2)
c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.Black)
c.SetLineWidth(1)
c.SetLineColor(generativeart.Orange)
@ -101,7 +120,6 @@ func main() {
```go
func julia1(z complex128) complex128 {
c := complex(-0.1, 0.651)
z = z*z + c
return z
@ -109,11 +127,11 @@ func julia1(z complex128) complex128 {
func main() {
rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 1.5, 1.5)
c := generativeart.NewCanva(500, 500)
c.SetIterations(800)
c.SetColorSchema(generativeart.Viridis)
c.FillBackground()
c.Draw(generativeart.NewJulia(julia1, 40))
c.Draw(generativeart.NewJulia(julia1, 40, 1.5, 1.5))
c.ToPNG("julia.png")
}
```
@ -125,12 +143,12 @@ func main() {
```go
func main() {
rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600, 2, 2)
c := generativeart.NewCanva(600, 600)
c.SetBackground(generativeart.Tan)
c.SetLineWidth(1.0)
c.SetLineColor(generativeart.LightPink)
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")
}
```
@ -142,7 +160,7 @@ func main() {
```go
func main() {
rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600, 1, 1)
c := generativeart.NewCanva(600, 600)
c.SetAlpha(10)
c.Draw(generativeart.NewSilkSky(15, 5))
c.ToPNG("silksky.png")
@ -156,12 +174,12 @@ func main() {
```go
func main() {
rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600, 2, 2)
c := generativeart.NewCanva(600, 600)
c.SetBackground(generativeart.Azure)
c.SetLineWidth(3)
c.SetLineColor(generativeart.Orange)
c.FillBackground()
c.Draw(generativeart.NewMaze())
c.Draw(generativeart.NewMaze(20))
c.ToPNG("maze.png")
}
```
@ -173,7 +191,7 @@ func main() {
```go
func main() {
rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(500, 500, 2, 2)
c := generativeart.NewCanva(500, 500)
c.SetBackground(generativeart.MistyRose)
c.SetLineWidth(1.0)
c.SetLineColor(color.RGBA{

View file

@ -11,17 +11,20 @@ type point struct {
}
type circleLine struct {
step float64
lineNum int
radius float64
step float64
lineNum int
radius float64
xaixs, yaixs float64
}
// 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{
step: step,
lineNum: lineNum,
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 {
x := cl.radius * math.Cos(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{
x: float64(xi),
y: float64(yi),

View file

@ -8,11 +8,11 @@ import (
func main() {
rand.Seed(time.Now().Unix())
c := generativeart.NewCanva(600, 600, 2, 2)
c := generativeart.NewCanva(600, 600)
c.SetBackground(generativeart.Tan)
c.SetLineWidth(1.0)
c.SetLineColor(generativeart.LightPink)
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")
}

View file

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

View file

@ -8,9 +8,9 @@ import (
func main() {
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.SetColorSchema(generativeart.DarkPink)
c.Draw(generativeart.NewGirdSquares())
c.Draw(generativeart.NewGirdSquares(24, 10, 0.2))
c.ToPNG("gsquare.png")
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -6,14 +6,17 @@ import "math/cmplx"
type GenFunc func(complex128) complex128
type julia struct {
fn GenFunc
maxz float64
fn GenFunc
maxz float64
xaixs, yaixs float64
}
func NewJulia(formula GenFunc, maxz float64) *julia {
func NewJulia(formula GenFunc, maxz, xaixs, yaixs float64) *julia {
return &julia{
fn: formula,
maxz: maxz,
fn: formula,
maxz: maxz,
xaixs: xaixs,
yaixs: yaixs,
}
}
@ -27,7 +30,7 @@ func (j *julia) Generative(c *canva) {
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*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 {
z = j.fn(z)

19
maze.go
View file

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

View file

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