add wave implementation and color

This commit is contained in:
Yongwei Xing 2021-02-26 16:09:37 +08:00
parent 41125ff1f8
commit 37b38f5ba2
5 changed files with 198 additions and 0 deletions

14
color.go Normal file
View file

@ -0,0 +1,14 @@
package generativeart
import "image/color"
var MistyRose = color.RGBA{0xFF, 0xE4, 0xE1, 0xFF}
var DarkSalmon = color.RGBA{0xE9, 0x96, 0x7A, 0xFF}
var Tan = color.RGBA{0xD2, 0xB4, 0x8C, 0xFF}
var Bisque = color.RGBA{0xFF, 0xE4, 0xC4, 0xFF}
var Mintcream = color.RGBA{0xF5, 0xFF, 0xFA, 0xFF}
var Aquamarine = color.RGBA{0x7F, 0xFF, 0xD4, 0xFF}
var Azure = color.RGBA{0xF0, 0xFF, 0xFF, 0xFF}
var Lavender = color.RGBA{0xE6, 0xE6, 0xFA, 0xFF}
var Plum = color.RGBA{0xDD, 0xA0, 0xDD, 0xFF}
var AntiqueWhite = color.RGBA{0xFA, 0xEB, 0xD7, 0xFF}

19
example/example.go Normal file
View file

@ -0,0 +1,19 @@
package main
import (
"generativeart"
"math"
)
func formula1(x, y float64) (float64, float64) {
return -0.13*x*x - math.Sin(y*y) + math.Cos(x*y),
-0.96*y*y*y - math.Cos(x*x)
}
func main() {
c := generativeart.NewCanva(800, 800, 4, 4)
c.FillBackgroud(generativeart.AntiqueWhite)
g := generativeart.NewWave(formula1)
g.GenerativePolar(c, generativeart.DarkSalmon)
c.ToPng("g1.png")
}

70
generativeart.go Normal file
View file

@ -0,0 +1,70 @@
package generativeart
import (
"image"
"image/color"
"image/draw"
"image/jpeg"
"image/png"
"os"
)
type Engine interface {
Generative(c *canva)
}
type canva struct {
height, width int
xaixs, yaixs float64
img *image.RGBA
}
func NewCanva(h, w int, x, y float64) *canva {
return &canva{
height: h,
width: w,
xaixs: x,
yaixs: y,
img: image.NewRGBA(image.Rect(0, 0, h, w)),
}
}
func (c *canva) FillBackgroud(rgba color.RGBA) {
draw.Draw(c.img, c.img.Bounds(), &image.Uniform{rgba}, image.ZP, draw.Src)
}
// ToPng saves the image to local with PNG format.
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 {
f.Close()
return err
}
if err := f.Close(); err != nil {
return err
}
return nil
}
// ToJpeg saves the image to local with Jpeg format.
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 {
f.Close()
return err
}
if err := f.Close(); err != nil {
return err
}
return nil
}

53
utils.go Normal file
View file

@ -0,0 +1,53 @@
package generativeart
import "math"
func ConvertCartesianToPixel(x, y, xaixs, yaixs float64, h, w int) (int, int) {
xr, yr := x/xaixs, y/yaixs
var i, j int
if xr > 0 {
i = w/2 + int(float64(w)/2*xr)
} else {
i = w/2 + int(float64(w)/2*xr)
}
if yr > 0 {
j = h/2 + int(float64(h)/2*yr)
} else {
j = h/2 + int(float64(h)/2*yr)
}
return i, j
}
func ConvertCartesianToPolarPixel(x, y, xaixs, yaixs float64, h, w int) (int, int) {
r, theta := ConvertCartesianToPolar(x, y)
return ConvertPolarToPixel(r, theta, xaixs, yaixs, h, w)
}
func ConvertCartesianToPolar(x, y float64) (float64, float64) {
r := math.Sqrt(x*x + y*y)
theta := math.Atanh(y / x)
return r, theta
}
func ConvertPolarToPixel(r, theta, xaixs, yaixs float64, h, w int) (int, int) {
x, y := r*math.Cos(theta), r*math.Sin(theta)
xr, yr := x/xaixs, y/yaixs
var i, j int
if xr > 0 {
i = w/2 + int(float64(w)/2*xr)
} else {
i = w/2 + int(float64(w)/2*xr)
}
if yr > 0 {
j = h/2 + int(float64(h)/2*yr)
} else {
j = h/2 + int(float64(h)/2*yr)
}
return i, j
}

42
wave.go Normal file
View file

@ -0,0 +1,42 @@
package generativeart
import (
"image/color"
"math"
)
type Formula func(x, y float64) (float64, float64)
type wave struct {
fn Formula
}
func NewWave(fn Formula) *wave {
return &wave{fn: fn}
}
func (w *wave) GenerativePolar(c *canva, rgba color.RGBA) {
for x := -math.Pi; x <= math.Pi; x += 0.01 {
for y := -math.Pi; y <= math.Pi; y += 0.01 {
xi, yi := w.fn(x, y)
i, j := ConvertCartesianToPolarPixel(xi, yi, c.xaixs, c.yaixs, c.height, c.width)
if i < 0 || i > c.width-1 || j < 0 || j > c.height-1 {
continue
}
c.img.Set(i, j, rgba)
}
}
}
func (w *wave) Generative(c *canva, rgba color.RGBA) {
for x := -math.Pi; x <= math.Pi; x += 0.008 {
for y := -math.Pi; y <= math.Pi; y += 0.008 {
xi, yi := w.fn(x, y)
i, j := ConvertCartesianToPixel(xi, yi, c.xaixs, c.yaixs, c.height, c.width)
if i < 0 || i > c.width-1 || j < 0 || j > c.height-1 {
continue
}
c.img.Set(i, j, rgba)
}
}
}