diff --git a/doc.go b/doc.go index 23bc747..d5236c0 100644 --- a/doc.go +++ b/doc.go @@ -35,7 +35,7 @@ Examples of nodes are the filter fields like [AbsFilter], [ClipFilter] and [Inve All of these require at least one source field in order to operate. Textures are built from the leaves upward until a root node has been created. -This node can then be passed to a function that will realize it, such as [NewRGBA] which generates +This node can then be passed to a function that will realize it, such as [NewTextureRGBA] which generates an [image.RGBA] by repeatedly calling the root's [ColorField] Eval2 function for each image pixel. # 3. Leaves - 1D @@ -84,7 +84,7 @@ to theta / (2 * Pi). # 4.3 Image (CF) -The image field uses the uderlying image to figure the color value to return for any given location. +The image field uses the underlying image to figure the color value to return for any given location. Supported interpolations are [NearestInterp], [LinearInterp], [CubicInterp], [P3Interp] and [P5Interp]. # 4.4 Perlin (F) diff --git a/example_flame_test.go b/example_flame_test.go new file mode 100644 index 0000000..5ca62ed --- /dev/null +++ b/example_flame_test.go @@ -0,0 +1,42 @@ +package texture_test + +import ( + "fmt" + "github.com/jphsd/graphics2d" + "github.com/jphsd/graphics2d/image" + "github.com/jphsd/texture" + "image/color" +) + +func Example_flames() { + f := texture.NewPerlin(12345) + + fx := texture.NewPerlin(12346) + + fy := texture.NewPerlin(12347) + + f2 := texture.NewDisplace(f, fx, fy, 1) + + xfm := graphics2d.Scale(1, 0.3) + f3 := texture.NewTransform(f2, xfm) + + img := texture.NewTextureGray16(600, 600, f3, 0, 0, .015, .015, false) + // Colorize it + c1, c2 := color.RGBA{0x19, 0, 0, 0xff}, color.RGBA{0xff, 0xff, 0x85, 0xff} + stops := []int{ + 64, + 128, + 160, + 250, + } + colors := []color.Color{ + color.RGBA{0x76, 0, 0, 0xff}, + color.RGBA{0xff, 0, 0, 0xff}, + color.RGBA{0xff, 0x7c, 0, 0xff}, + color.RGBA{0xff, 0xff, 0x7a, 0xff}, + } + img2 := image.NewColorizer(img, c1, c2, stops, colors, false) + image.SaveImage(img2, "Example_flames") + fmt.Printf("Generated Example_flames") + // Output: Generated Example_flames +} diff --git a/examples_test.go b/examples_test.go new file mode 100644 index 0000000..5d6f058 --- /dev/null +++ b/examples_test.go @@ -0,0 +1,253 @@ +package texture_test + +import ( + "fmt" + "github.com/jphsd/graphics2d" + "github.com/jphsd/graphics2d/image" + "github.com/jphsd/texture" + "math" +) + +func ExampleLinearGradient_Saw() { + nl := texture.NewNLLinear() + w := texture.NewNLWave([]float64{125}, []*texture.NonLinear{nl}, false, false) + f := texture.NewLinearGradient(w) + + img := texture.NewTextureGray16(600, 600, f, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleLinearGradient_Saw") + fmt.Printf("Generated ExampleLinearGradient_Saw") + // Output: Generated ExampleLinearGradient_Saw +} + +func ExampleLinearGradient_Triangle() { + nl := texture.NewNLLinear() + w := texture.NewNLWave([]float64{125}, []*texture.NonLinear{nl}, true, false) + f := texture.NewLinearGradient(w) + + img := texture.NewTextureGray16(600, 600, f, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleLinearGradient_Triangle") + fmt.Printf("Generated ExampleLinearGradient_Triangle") + // Output: Generated ExampleLinearGradient_Triangle +} + +func ExampleLinearGradient_Sine() { + nl := texture.NewNLSin() + w := texture.NewNLWave([]float64{125}, []*texture.NonLinear{nl}, true, false) + f := texture.NewLinearGradient(w) + + img := texture.NewTextureGray16(600, 600, f, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleLinearGradient_Sine") + fmt.Printf("Generated ExampleLinearGradient_Sine") + // Output: Generated ExampleLinearGradient_Sine +} + +func ExampleMulCombiner() { + nl := texture.NewNLSin() + w := texture.NewNLWave([]float64{125}, []*texture.NonLinear{nl}, true, false) + f := texture.NewLinearGradient(w) + + xfm := graphics2d.Rotate(graphics2d.HalfPi) + f2 := texture.NewTransform(f, xfm) + + f3 := texture.NewMulCombiner(f, f2) + + img := texture.NewTextureGray16(600, 600, f3, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleMulCombiner") + fmt.Printf("Generated ExampleMulCombiner") + // Output: Generated ExampleMulCombiner +} + +func ExampleMaxCombiner() { + nl := texture.NewNLSin() + w := texture.NewNLWave([]float64{125}, []*texture.NonLinear{nl}, true, false) + f := texture.NewLinearGradient(w) + + xfm := graphics2d.Rotate(graphics2d.HalfPi) + f2 := texture.NewTransform(f, xfm) + + f3 := texture.NewMaxCombiner(f, f2) + + img := texture.NewTextureGray16(600, 600, f3, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleMaxCombiner") + fmt.Printf("Generated ExampleMaxCombiner") + // Output: Generated ExampleMaxCombiner +} + +func ExampleLinearGradient_Circular() { + nl1 := texture.NewNLCircle1() + nl2 := texture.NewNLCircle2() + w := texture.NewDCWave([]float64{125}, []*texture.NonLinear{nl1, nl2}, false) + f := texture.NewLinearGradient(w) + + img := texture.NewTextureGray16(600, 600, f, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleLinearGradient_Circular") + fmt.Printf("Generated ExampleLinearGradient_Circular") + // Output: Generated ExampleLinearGradient_Circular +} + +func ExampleRadialGradient_Saw() { + nl := texture.NewNLLinear() + w := texture.NewNLWave([]float64{125}, []*texture.NonLinear{nl}, false, false) + f := texture.NewRadialGradient(w) + + img := texture.NewTextureGray16(600, 600, f, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleRadialGradient_Saw") + fmt.Printf("Generated ExampleRadialGradient_Saw") + // Output: Generated ExampleRadialGradient_Saw +} + +func ExampleRadialGradient_Triangle() { + nl := texture.NewNLLinear() + w := texture.NewNLWave([]float64{125}, []*texture.NonLinear{nl}, true, false) + f := texture.NewRadialGradient(w) + + img := texture.NewTextureGray16(600, 600, f, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleRadialGradient_Triangle") + fmt.Printf("Generated ExampleRadialGradient_Triangle") + // Output: Generated ExampleRadialGradient_Triangle +} + +func ExampleRadialGradient_Sine() { + nl := texture.NewNLSin() + w := texture.NewNLWave([]float64{125}, []*texture.NonLinear{nl}, true, false) + f := texture.NewRadialGradient(w) + + img := texture.NewTextureGray16(600, 600, f, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleRadialGradient_Sine") + fmt.Printf("Generated ExampleRadialGradient_Sine") + // Output: Generated ExampleRadialGradient_Sine +} + +func ExampleRadialGradient_Circular() { + nl1 := texture.NewNLCircle1() + nl2 := texture.NewNLCircle2() + w := texture.NewDCWave([]float64{125}, []*texture.NonLinear{nl1, nl2}, false) + f := texture.NewRadialGradient(w) + + img := texture.NewTextureGray16(600, 600, f, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleRadialGradient_Circular") + fmt.Printf("Generated ExampleRadialGradient_Circular") + // Output: Generated ExampleRadialGradient_Circular +} + +func ExampleConicGradient() { + nl := texture.NewNLSin() + w := texture.NewNLWave([]float64{125, 125, 125}, []*texture.NonLinear{nl, nl, nl}, true, false) + f := texture.NewConicGradient(w) + + img := texture.NewTextureGray16(600, 600, f, -300, -300, 1, 1, false) + image.SaveImage(img, "ExampleConicGradient") + fmt.Printf("Generated ExampleConicGradient") + // Output: Generated ExampleConicGradient +} + +func ExamplePerlin() { + f := texture.NewPerlin(12345) + + img := texture.NewTextureGray16(600, 600, f, 0, 0, .015, .015, false) + image.SaveImage(img, "ExamplePerlin") + fmt.Printf("Generated ExamplePerlin") + // Output: Generated ExamplePerlin +} + +func ExampleDisplace() { + f := texture.NewPerlin(12345) + + fx := texture.NewPerlin(12346) + + fy := texture.NewPerlin(12347) + + f2 := texture.NewDisplace(f, fx, fy, 1) + + img := texture.NewTextureGray16(600, 600, f2, 0, 0, .015, .015, false) + image.SaveImage(img, "ExampleDisplace") + fmt.Printf("Generated ExampleDisplace") + // Output: Generated ExampleDisplace +} + +func ExampleTriangles() { + f := texture.NewTriangles(40) + + img := texture.NewTextureGray16(600, 600, f, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleTriangles") + fmt.Printf("Generated ExampleTriangles") + // Output: Generated ExampleTriangles +} + +func ExampleTransform() { + f := texture.NewTriangles(40) + + // Apply a transform to convert to equilateral triangles + xfm := graphics2d.Rotate(-math.Pi / 4) + xfm.Scale(math.Sqrt2, 1) + f2 := texture.NewTransform(f, xfm) + + img := texture.NewTextureGray16(600, 600, f2, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleTransform") + fmt.Printf("Generated ExampleTransform") + // Output: Generated ExampleTransform +} + +func ExampleSquares() { + f := texture.NewSquares(40) + + img := texture.NewTextureGray16(600, 600, f, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleSquares") + fmt.Printf("Generated ExampleSquares") + // Output: Generated ExampleSquares +} + +func ExampleHexagons() { + f := texture.NewHexagons(20) + + img := texture.NewTextureGray16(600, 600, f, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleHexagons") + fmt.Printf("Generated ExampleHexagons") + // Output: Generated ExampleHexagons +} + +func ExampleBlend() { + f := texture.NewHexagons(20) + + f2 := texture.NewSquares(40) + + nl := texture.NewNLLinear() + w := texture.NewNLWave([]float64{600}, []*texture.NonLinear{nl}, false, false) + f3 := texture.NewLinearGradient(w) + + f4 := texture.NewBlend(f, f2, f3) + + img := texture.NewTextureGray16(600, 600, f4, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleBlend") + fmt.Printf("Generated ExampleBlend") + // Output: Generated ExampleBlend +} + +func ExampleShape() { + shape := graphics2d.NewShape(graphics2d.ReentrantPolygon([]float64{300, 300}, 300, 5, .65, 0)) + f := texture.NewShape(shape, texture.BinaryStyle) + + img := texture.NewTextureGray16(600, 600, f, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleShape") + fmt.Printf("Generated ExampleShape") + // Output: Generated ExampleShape +} + +func ExampleShapeCombiner() { + nl := texture.NewNLSin() + w := texture.NewNLWave([]float64{32}, []*texture.NonLinear{nl}, true, false) + f := texture.NewRadialGradient(w) + + xfm := graphics2d.Translate(-300, -300) + f2 := texture.NewTransform(f, xfm) + + f3 := texture.NewSquares(40) + + shape := graphics2d.NewShape(graphics2d.ReentrantPolygon([]float64{300, 300}, 300, 5, .65, 0)) + f4 := texture.NewShapeCombiner(f2, f3, shape) + + img := texture.NewTextureGray16(600, 600, f4, 0, 0, 1, 1, false) + image.SaveImage(img, "ExampleShapeCombiner") + fmt.Printf("Generated ExampleShapeCombiner") + // Output: Generated ExampleShapeCombiner +}