generativeart/arts/circleloop2.go

82 lines
2.1 KiB
Go

package arts
import (
"github.com/fogleman/gg"
"github.com/jdxyw/generativeart"
"github.com/jdxyw/generativeart/common"
"math"
"math/rand"
)
type circleLoop2 struct {
depth int
noise *common.PerlinNoise
}
func NewCircleLoop2(depth int) *circleLoop2 {
return &circleLoop2{
depth: depth,
noise: common.NewPerlinNoise(),
}
}
// Generative draws a circle composed by many colored circles.
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 *generativeart.Canva, x float64, depth int) {
if depth <= 0 {
return
}
cl.draw(ctex, c, x)
cl.recursionDraw(ctex, c, 1*x/4.0, depth-1)
cl.recursionDraw(ctex, c, 2*x/4.0, depth-1)
cl.recursionDraw(ctex, c, 3*x/4.0, depth-1)
}
func (cl *circleLoop2) draw(ctex *gg.Context, c *generativeart.Canva, x float64) {
var lw float64
if rand.Float64() < 0.8 {
lw = 1
} else {
lw = common.RandomRangeFloat64(1.0, common.RandomRangeFloat64(1, 3))
}
ctex.SetLineWidth(lw)
noise := cl.noise.Noise3D(x*0.02+123.234, (1-x)*0.02, 345.4123)
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)))
cls := c.Opts().ColorSchema()[rand.Intn(len(c.Opts().ColorSchema()))]
ctex.SetColor(cls)
nCircles := common.RandomRangeInt(1, 6)
if rand.Float64() < 0.03 {
nCircles = common.RandomRangeInt(8, 10)
}
r := math.Pow(rand.Float64(), 2) * 50
var flag bool
if rand.Float64() < 0.7 {
flag = true
}
for i := 0; i < nCircles; i++ {
if flag {
ctex.DrawCircle(px*0.39, py*0.39, rand.Float64()*float64(i)*r/float64(nCircles))
} else {
ctex.DrawCircle(px*0.39, py*0.39, float64(i)*r/float64(nCircles))
}
ctex.Stroke()
}
ctex.Rotate(x / float64(c.Height()) * 0.2)
}