major refractor: move the arts to different folder and export the canve.

This commit is contained in:
Yongwei Xing 2021-03-16 12:04:05 +08:00
parent 27fac585da
commit aec13501e1
53 changed files with 451 additions and 355 deletions

View File

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

View File

@ -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),

View File

@ -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()

View File

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

View File

@ -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

View File

@ -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++ {

View File

@ -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

View File

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

View File

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

49
arts/dotswave.go Normal file
View File

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

View File

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

46
arts/julia.go Normal file
View File

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

View File

@ -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 {

View File

@ -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++ {

View File

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

View File

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

View File

@ -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

View File

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

View File

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

View File

@ -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()

View File

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

View File

@ -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

View File

@ -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()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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