82 lines
2.1 KiB
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)
|
|
}
|