add perlin perls
This commit is contained in:
parent
ed10f4403d
commit
a8740b437e
10 changed files with 198 additions and 5 deletions
21
README.md
21
README.md
|
@ -33,6 +33,7 @@
|
|||
- [Circle Loop](#circle-loop)
|
||||
- [Domain Warp](#domain-warp)
|
||||
- [Circle Noise](#circle-noise)
|
||||
- [Perlin Perls](#perlin-perls)
|
||||
- [Color Canva](#color-canva)
|
||||
- [Julia Set](#julia-set)
|
||||
- [Black Hole](#black-hole)
|
||||
|
@ -83,6 +84,7 @@ This package is still working in progress. More types would be added. Welcome an
|
|||
- Black Hole
|
||||
- Color Canva
|
||||
- Domain Warp
|
||||
- Perlin Perls
|
||||
|
||||
For these kinds of art, the package provides as many parameters to control the appearance.
|
||||
|
||||
|
@ -123,6 +125,7 @@ NewYarn(n int)
|
|||
NewBlackHole(circleN int, density, circleGap float64)
|
||||
NewColorCanve(seg float64)
|
||||
NewDomainWrap(scale, scale2, xOffset, yOffset float64, cmap ColorMapping)
|
||||
NewPerlinPerls(circleN, dotsN, colorMin, colorMax int)
|
||||
```
|
||||
|
||||
## Docs
|
||||
|
@ -460,6 +463,24 @@ func main() {
|
|||
|
||||
![](images/circlenoise.png)
|
||||
|
||||
### Perlin Perls
|
||||
|
||||
```go
|
||||
func main() {
|
||||
rand.Seed(time.Now().Unix())
|
||||
c := generativeart.NewCanva(500, 500)
|
||||
c.SetBackground(common.White)
|
||||
c.SetAlpha(120)
|
||||
c.SetLineWidth(0.3)
|
||||
c.FillBackground()
|
||||
c.SetIterations(200)
|
||||
c.Draw(arts.NewPerlinPerls(10, 200, 40, 80))
|
||||
c.ToPNG("perlinperls.png")
|
||||
}
|
||||
```
|
||||
|
||||
![](../images/perlinperls.png)
|
||||
|
||||
### Color Canva
|
||||
|
||||
```go
|
||||
|
|
|
@ -18,6 +18,7 @@ type dot struct {
|
|||
prevx, prevy float64
|
||||
theta float64
|
||||
count int
|
||||
cx, cy float64
|
||||
}
|
||||
|
||||
func NewCircleNoise(dotsN, colorMin, colorMax int) *circleNoise {
|
||||
|
|
|
@ -12,7 +12,7 @@ type ColorMapping func(float64, float64, float64) color.RGBA
|
|||
type domainWrap struct {
|
||||
noise *common.PerlinNoise
|
||||
scale float64
|
||||
scale2 float64
|
||||
scale2 float64
|
||||
xOffset, yOffset float64
|
||||
fn ColorMapping
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ type domainWrap struct {
|
|||
func NewDomainWrap(scale, scale2, xOffset, yOffset float64, cmap ColorMapping) *domainWrap {
|
||||
return &domainWrap{
|
||||
scale: scale,
|
||||
scale2: scale2,
|
||||
scale2: scale2,
|
||||
xOffset: xOffset,
|
||||
yOffset: yOffset,
|
||||
noise: common.NewPerlinNoise(),
|
||||
|
|
123
arts/perlinpearls.go
Normal file
123
arts/perlinpearls.go
Normal file
|
@ -0,0 +1,123 @@
|
|||
package arts
|
||||
|
||||
import (
|
||||
"github.com/fogleman/gg"
|
||||
"github.com/jdxyw/generativeart"
|
||||
"github.com/jdxyw/generativeart/common"
|
||||
"math"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
type perlinPearls struct {
|
||||
circleN int
|
||||
dotsN int
|
||||
colorMin, colorMax int
|
||||
}
|
||||
|
||||
type circles struct {
|
||||
x, y float64
|
||||
radius float64
|
||||
colorMin, colorMax int
|
||||
}
|
||||
|
||||
func NewPerlinPerls(circleN, dotsN, colorMin, colorMax int) *perlinPearls {
|
||||
return &perlinPearls{
|
||||
circleN: circleN,
|
||||
dotsN: dotsN,
|
||||
colorMin: colorMin,
|
||||
colorMax: colorMax,
|
||||
}
|
||||
}
|
||||
|
||||
// Generative draws a circle with perlin noise.
|
||||
func (pp *perlinPearls) Generative(c *generativeart.Canva) {
|
||||
ctex := gg.NewContextForRGBA(c.Img())
|
||||
ctex.SetLineWidth(0.5)
|
||||
ctex.SetColor(common.Black)
|
||||
|
||||
cs := make([]circles, 0)
|
||||
|
||||
for len(cs) < pp.circleN {
|
||||
c := circles{
|
||||
x: common.RandomRangeFloat64(100, float64(c.Width())-50),
|
||||
y: common.RandomRangeFloat64(100, float64(c.Height())-50),
|
||||
radius: common.RandomRangeFloat64(20, 100),
|
||||
colorMin: pp.colorMin,
|
||||
colorMax: pp.colorMax,
|
||||
}
|
||||
var overlapping bool
|
||||
for _, cl := range cs {
|
||||
d := common.Distance(c.x, c.y, cl.x, cl.y)
|
||||
if d < c.radius+cl.radius {
|
||||
overlapping = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if overlapping == false {
|
||||
cs = append(cs, c)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ds := make([][]dot, 0)
|
||||
|
||||
for i := 0; i < pp.circleN; i++ {
|
||||
dots := make([]dot, 0)
|
||||
for j := 0; j < pp.dotsN; j++ {
|
||||
theta := rand.Float64() * math.Pi * 2
|
||||
//x, y := float64(c.Width())/2+math.Sin(theta)*radius, float64(c.Height())/2+math.Cos(theta)*radius
|
||||
dots = append(dots, dot{
|
||||
theta: theta,
|
||||
cx: cs[i].x,
|
||||
cy: cs[i].y,
|
||||
x: cs[i].x + math.Sin(theta)*cs[i].radius,
|
||||
y: cs[i].y + math.Cos(theta)*cs[i].radius,
|
||||
prevx: cs[i].x + math.Sin(theta)*cs[i].radius,
|
||||
prevy: cs[i].y + math.Cos(theta)*cs[i].radius,
|
||||
count: 0,
|
||||
})
|
||||
}
|
||||
|
||||
ds = append(ds, dots)
|
||||
}
|
||||
|
||||
noise := common.NewPerlinNoise()
|
||||
|
||||
for i := 0; i < pp.circleN; i++ {
|
||||
ctex.SetLineWidth(0.5)
|
||||
ctex.SetColor(common.Black)
|
||||
ctex.DrawCircle(cs[i].x, cs[i].y, cs[i].radius)
|
||||
ctex.Stroke()
|
||||
|
||||
var factor = 0.008
|
||||
for j := 0; j < c.Opts().NIters(); j++ {
|
||||
for k := range ds[i] {
|
||||
n := noise.Noise2D(ds[i][k].x*factor, ds[i][k].y*factor)
|
||||
nx, ny := math.Cos(n*math.Pi*2+float64(ds[i][k].count)*math.Pi)*2, math.Sin(n*math.Pi*2+float64(ds[i][k].count)*math.Pi)*2
|
||||
ds[i][k].prevx, ds[i][k].prevy = ds[i][k].x, ds[i][k].y
|
||||
ds[i][k].x, ds[i][k].y = ds[i][k].x+nx, ds[i][k].y+ny
|
||||
|
||||
hsv := common.HSV{
|
||||
H: int(common.Remap(n, 0, 1, float64(cs[i].colorMin), float64(cs[i].colorMax))),
|
||||
S: 100,
|
||||
V: 20,
|
||||
}
|
||||
|
||||
if common.Distance(cs[i].x, cs[i].y, ds[i][k].x, ds[i][k].y) > cs[i].radius+1 {
|
||||
ds[i][k].count += 1
|
||||
}
|
||||
|
||||
if common.Distance(cs[i].x, cs[i].y, ds[i][k].x, ds[i][k].y) < cs[i].radius &&
|
||||
common.Distance(cs[i].x, cs[i].y, ds[i][k].prevx, ds[i][k].prevy) < cs[i].radius {
|
||||
ctex.SetLineWidth(c.Opts().LineWidth())
|
||||
rgb := hsv.ToRGB(100, 100, 100)
|
||||
rgb.A = uint8(c.Opts().Alpha())
|
||||
ctex.SetColor(rgb)
|
||||
ctex.DrawLine(ds[i][k].prevx, ds[i][k].prevy, ds[i][k].x, ds[i][k].y)
|
||||
ctex.Stroke()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,3 +15,13 @@ func (v *Vector) Multiple(z float64) {
|
|||
v.X = v.X * z
|
||||
v.Y = v.Y * z
|
||||
}
|
||||
|
||||
func (v *Vector) Normalize() {
|
||||
l := Magnitude(v.X, v.Y)
|
||||
v.Multiple(1 / l)
|
||||
}
|
||||
|
||||
func (v *Vector) SetMag(m float64) {
|
||||
v.Normalize()
|
||||
v.Multiple(m)
|
||||
}
|
||||
|
|
19
docs/doc.md
19
docs/doc.md
|
@ -38,6 +38,8 @@
|
|||
- [parameters](#parameters-16)
|
||||
- [Domain Warping](#domain-warping)
|
||||
- [parameters](#parameters-17)
|
||||
- [Perlin Perls](#perlin-perls)
|
||||
- [parameters](#parameters-18)
|
||||
|
||||
## Color Circle 2
|
||||
|
||||
|
@ -281,4 +283,19 @@ Warping, or domain distortion is a very common technique in computer graphics fo
|
|||
d := arts.NewDomainWrap(0.01, 4, 8, cmap)
|
||||
```
|
||||
|
||||
![](../images/domainwarp.png)
|
||||
![](../images/domainwarp.png)
|
||||
|
||||
## Perlin Perls
|
||||
|
||||
### parameters
|
||||
|
||||
- circleN: The number of circle on this image.
|
||||
- dotsN: The number of dots in each circle.
|
||||
- colorMin: The minimum color.
|
||||
- colorMax: The maximum color.
|
||||
|
||||
```go
|
||||
pp := arts.NewPerlinPerls(10, 200, 40, 80
|
||||
```
|
||||
|
||||
![](../images/perlinperls.png)
|
|
@ -12,7 +12,7 @@ func main() {
|
|||
rand.Seed(time.Now().Unix())
|
||||
c := generativeart.NewCanva(500, 500)
|
||||
c.SetBackground(common.White)
|
||||
c.SetAlpha(80)
|
||||
c.SetAlpha(5)
|
||||
c.SetLineWidth(0.3)
|
||||
c.FillBackground()
|
||||
c.SetIterations(400)
|
||||
|
|
|
@ -24,6 +24,6 @@ func main() {
|
|||
c := generativeart.NewCanva(500, 500)
|
||||
c.SetBackground(common.Black)
|
||||
c.FillBackground()
|
||||
c.Draw(arts.NewDomainWrap(0.01, 4,4, 20, cmap))
|
||||
c.Draw(arts.NewDomainWrap(0.01, 4, 4, 20, cmap))
|
||||
c.ToPNG("domainwarp.png")
|
||||
}
|
||||
|
|
21
example/example_perlinpearls.go
Normal file
21
example/example_perlinpearls.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/jdxyw/generativeart"
|
||||
"github.com/jdxyw/generativeart/arts"
|
||||
"github.com/jdxyw/generativeart/common"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().Unix())
|
||||
c := generativeart.NewCanva(500, 500)
|
||||
c.SetBackground(common.White)
|
||||
c.SetAlpha(120)
|
||||
c.SetLineWidth(0.3)
|
||||
c.FillBackground()
|
||||
c.SetIterations(200)
|
||||
c.Draw(arts.NewPerlinPerls(10, 200, 40, 80))
|
||||
c.ToPNG("perlinperls.png")
|
||||
}
|
BIN
images/perlinperls.png
Normal file
BIN
images/perlinperls.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 223 KiB |
Loading…
Reference in a new issue