gog

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 28, 2024 License: BSD-3-Clause Imports: 15 Imported by: 0

README

gog

gog is a Go Object-oriented 2d drawing library for generative art

Instead of immediate drawing, each shape is a Path{} struct made up of points. The Path has Fill() Stroke() FillStroke() StrokeFill() functions for drawing on the canvas. There is also a DebugDraw() function for Debug purposes that draws all the properties of the Path.

All transformations are applied with reference to the Path.Anchor{} point.

  • Path.Translate()
  • Path.SetPos()
  • Path.Rotate()
  • Path.Rotated()
  • Path.Scale()

It is possible to write the canvas (Go standard package image surface) as a static PNG file or APNG animation.

package main

import (
	"github.com/setanarut/gog"
	"image/color"
)

func main() {
	c := gog.New(250, 250)
	curve := gog.CubicBezier(100, 95, 50, 300, 190, 88, 140, 200)
	curve.SetPos(c.Center).Scale(gog.P(1.3, 1.3))
	for i := 0; i < 150; i++ {
		c.Clear(color.Gray{30})
		curve.Rotate((gog.Pi * 2) / 150)
		c.DebugDraw(curve)
		c.AppendAnimationFrame()
	}
	c.SaveAPNG("curve_anim.png", 3)
}

curve

Motion path example

rect := gog.Rect(gog.Point{}, 30, 10)
ellipse := gog.Circle(c.Center, 50).Scale(gog.P(1, 0.5))
for _, t := range gog.Linspace(0, 1, 150) {
	c.Clear(gog.Black)
	ellipse.Stroke(c)
	p, a := ellipse.PointAngleAtTime(t)
	rect.SetPos(p).Rotated(a).SetFill(colornames.Yellow).Fill(c)
	c.AppendAnimationFrame()
}

Full code is available in example folder

curve

Documentation

Overview

Package gog is a Go Drawing Library

Example

150-frame rotating cubic bezier APNG animation

package main

import (
	"fmt"
	"image/color"

	"github.com/setanarut/gog"
)

func main() {
	ctx := gog.New(250, 250)
	curve := gog.CubicBezier(100, 95, 50, 300, 190, 88, 140, 200)
	curve.SetPos(ctx.Center)
	for i := 0; i < 150; i++ {
		ctx.Clear(color.Gray{30})
		curve.Rotate((gog.Pi * 2) / 150)
		ctx.DebugDraw(curve)
		ctx.AppendAnimationFrame()
	}
	// ctx.SaveAPNG("anim.png", 3)
	fmt.Println(len(ctx.AnimationFrames))
}
Output:

150

Index

Examples

Constants

This section is empty.

Variables

View Source
var Black = color.Black
View Source
var Gray = color.Gray{128}
View Source
var Gray40 = color.Gray{40}
View Source
var White = color.White

Functions

func Linspace

func Linspace(start, stop float64, num int) (res []float64)

Linspace returns evenly spaced numbers over a specified closed interval.

func New

func New(width, height int) *context

New returns a new drawing context.

func Radians

func Radians(degree float64) float64

Radians converts degrees to radians

func TangentAngle

func TangentAngle(start, end Point) float64

TangentAngle return tangent angle of two points

Types

type CapMode

type CapMode uint8
const (
	ButtCap CapMode = iota
	SquareCap
	RoundCap
	CubicCap
	QuadraticCap
)

CapMode constants determines line cap style

type DrawMode

type DrawMode uint8

type JoinMode

type JoinMode uint8
const (
	MiterJoin JoinMode = iota
	RoundJoin
	BevelJoin
)

JoinMode constants determine how stroke segments bridge the gap at a join

type Path

type Path struct {

	// Style holds the fill color, line color, thickness and DrawMode options.
	Style Style
	// Anchor point
	Anchor Point
	// contains filtered or unexported fields
}

Path object

func BBox

func BBox(min, max Point) *Path

BBox returns a bounding box path with min and max points.

func Circle

func Circle(origin Point, radius float64) *Path

Circle returns circle-shaped Path.

func CubicBezier

func CubicBezier(x0, y0, x1, y1, x2, y2, x3, y3 float64) *Path

CubicBezier returns a cubic-bezier Path.

func Ellipse

func Ellipse(origin Point, xRadius, yRadius float64) *Path

Ellipse returns ellipse-shaped Path.

func Line

func Line(start, end Point) *Path

Line returns a line Path.

Example

Creates new line and prints start and end point

package main

import (
	"fmt"

	"github.com/setanarut/gog"
)

func main() {
	line := gog.Line(gog.Point{X: 0, Y: 0}, gog.Point{X: 25, Y: 80})
	fmt.Println(line.Start(), line.End())
}
Output:

{0 0} {25 80}

func NewPath

func NewPath(points []Point) *Path

NewPath returns new Path from points

func Rect

func Rect(topLeft Point, w, h float64) *Path

Rect returns a rectangle-shaped Path.

func RegularPolygon

func RegularPolygon(origin Point, n int, radius float64) *Path

RegularPolygon returns regular polygon shaped Path.

func Square

func Square(topLeft Point, side float64) *Path

Square returns Square-shaped Path with side.

func (*Path) AppendPoints added in v0.5.1

func (p *Path) AppendPoints(points ...Point) *Path

AppendPoints appends points to the end of the Path

func (*Path) Bounds

func (p *Path) Bounds() (Point, Point)

Bounds returns bounds min/max

func (*Path) Centroid

func (p *Path) Centroid() Point

Centroid Calculates and returns the path's centroid point

func (*Path) Clone

func (p *Path) Clone() *Path

Clone returns copy of path

func (*Path) Close

func (p *Path) Close() *Path

Close closes Path

func (*Path) DebugDraw

func (p *Path) DebugDraw(c *context) *Path

DebugDraw draw for debug

func (*Path) DeleteAtIndex added in v0.5.1

func (p *Path) DeleteAtIndex(index int) *Path

DeleteAtIndex removes point from Path at index if the number of points is more than two.

func (*Path) DeleteEnd added in v0.5.1

func (p *Path) DeleteEnd() *Path

DeleteEnd removes end point of the Path if the number of points is more than two.

func (*Path) End

func (p *Path) End() Point

End returns end point of Path

func (*Path) Fill

func (p *Path) Fill(c *context) *Path

Fill fills the path and draws it on the canvas.

func (*Path) FillStroke

func (p *Path) FillStroke(c *context) *Path

FillStroke fills then strokes path

func (*Path) GetPoints added in v0.5.1

func (p *Path) GetPoints() []Point

GetPoints return points

func (*Path) InsertAtIndex added in v0.5.1

func (p *Path) InsertAtIndex(pnt Point, index int) *Path

InsertAtIndex inserts point to the Path at index

Example

Insert point to path points at index

package main

import (
	"github.com/setanarut/gog"
)

func main() {
	line := gog.NewPath([]gog.Point{{0, 0}, {10, 10}})
	line.InsertAtIndex(gog.Point{66, 66}, 1)
	line.PrintPoints()
}
Output:

[{0 0} {66 66} {10 10}]

func (*Path) InsertAtLength added in v0.5.1

func (p *Path) InsertAtLength(length float64)

InsertAtLength inserts point at length if coord is empty

Example
package main

import (
	"github.com/setanarut/gog"
)

func main() {
	line := gog.NewPath([]gog.Point{{0, 0}, {0, 10}, {0, 20}})
	line.InsertAtLength(10.5)
	line.PrintPoints()
}
Output:

[{0 0} {0 10} {0 10.5} {0 20}]s

func (*Path) InsertAtTime added in v0.5.1

func (p *Path) InsertAtTime(t float64)

InsertAtTime inserts point at time

func (*Path) IsClosed

func (p *Path) IsClosed() bool

IsClosed returns true if Path closed

func (Path) Len

func (p Path) Len() int

Len returns number of points

func (Path) Length

func (p Path) Length() float64

Length returns total length of Path

func (*Path) Open

func (p *Path) Open() *Path

Open opens Path

func (*Path) Perpendicular

func (p *Path) Perpendicular(t float64, length float64) (p1 Point, p2 Point)

Returns Perpendicular line points at time t with length

func (*Path) PointAngleAtLength added in v0.5.1

func (p *Path) PointAngleAtLength(length float64) (Point, float64)

PointAngleAtLength Returns point and tangent angle at length

Example

Get point and tangent angle at length

package main

import (
	"fmt"

	"github.com/setanarut/gog"
)

func main() {
	line := gog.NewPath([]gog.Point{{X: 0, Y: 0}, {X: 10, Y: 10}})
	point, angle := line.PointAngleAtLength(line.Length() / 2)
	fmt.Println(point, angle)
}
Output:

{5 5} 0.7853981633974483

func (*Path) PointAngleAtTime added in v0.5.1

func (p *Path) PointAngleAtTime(t float64) (Point, float64)

PointAngleAtTime Returns point and tangent angle at time t

Example

Get point and tangent angle at time t

package main

import (
	"fmt"

	"github.com/setanarut/gog"
)

func main() {
	line := gog.NewPath([]gog.Point{{X: 0, Y: 0}, {X: 10, Y: 10}})
	point, angle := line.PointAngleAtTime(0.5)
	fmt.Println(point, angle)
}
Output:

{5 5} 0.7853981633974483

func (*Path) PointAtIndex added in v0.5.1

func (p *Path) PointAtIndex(index int) Point

PointAtIndex returns point at index

func (*Path) PrintPoints added in v0.5.1

func (p *Path) PrintPoints()

PrintPoints prints path points to standard output.

func (*Path) RemoveDoubles added in v0.5.1

func (p *Path) RemoveDoubles() *Path

RemoveDoubles removes double points

Example
package main

import (
	"fmt"

	"github.com/setanarut/gog"
)

func main() {
	path := gog.NewPath([]gog.Point{{0, 0}, {77, 77}, {77, 77}, {0, 0}, {0, 0}})
	path.RemoveDoubles()
	fmt.Println(path.GetPoints())
}
Output:

[{0 0} {77 77} {0 0}]

func (*Path) ResetAnchor

func (p *Path) ResetAnchor() *Path

ResetAnchor sets anchor point to centroid

func (*Path) Reverse

func (p *Path) Reverse() *Path

Reverse reverses Path. The starting point becomes the end and the end becomes the beginning.

func (*Path) Rotate

func (p *Path) Rotate(angle float64) *Path

Rotate rotates the Path about Path.Anchor point

func (*Path) Rotated added in v1.0.0

func (p *Path) Rotated(angle float64) *Path

Rotated returns new rotated Path about Path.Anchor point

func (*Path) Scale

func (p *Path) Scale(factor Point) *Path

Scale scales the Path at the Anchor point.

func (*Path) SetAnchor

func (p *Path) SetAnchor(pt Point) *Path

SetAnchor Sets Path's anchor point

Example
package main

import (
	"fmt"

	"github.com/setanarut/gog"
)

func main() {
	line := gog.NewPath([]gog.Point{{X: 0, Y: 0}, {X: 10, Y: 10}})
	fmt.Println(line.Anchor) // Centroid of Path
	line.SetAnchor(gog.Point{X: 3, Y: 3})
	fmt.Println(line.Anchor)
	line.ResetAnchor()
	fmt.Println(line.Anchor)
	fmt.Println(line.Centroid() == line.Anchor)
}
Output:

{5 5}
{3 3}
{5 5}
true

func (*Path) SetFill

func (p *Path) SetFill(c color.Color) *Path

SetFill sets fill color of Path.

func (*Path) SetLineWidth

func (p *Path) SetLineWidth(w float64) *Path

SetLineWidth sets line thickness of Path.

func (*Path) SetPos

func (p *Path) SetPos(position Point) *Path

SetPos Aligns the Path with the anchor point to the desired point. In other words, it sets the position.

func (*Path) SetStroke

func (p *Path) SetStroke(c color.Color) *Path

SetStroke sets stroke color of Path.

func (*Path) SetStyle

func (p *Path) SetStyle(s Style) *Path

SetStyle sets Style of Path.

func (*Path) Start

func (p *Path) Start() Point

Start returns start point of Path

func (*Path) Stroke

func (p *Path) Stroke(c *context) *Path

Stroke Draw the path as a stroke

func (*Path) StrokeFill

func (p *Path) StrokeFill(c *context) *Path

StrokeFill stroke then fill path

func (*Path) Translate

func (p *Path) Translate(x, y float64) *Path

Translate translates the Path

type Point

type Point struct {
	X, Y float64
}

A Point is an X, Y coordinate pair. The axes increase right and down.

func P

func P(x, y float64) Point

P shorthand for Point{} struct

func (Point) Add

func (p Point) Add(q Point) Point

Add returns the vector p+q.

func (Point) Distance

func (a Point) Distance(other Point) float64

Distance to other point

func (Point) Div

func (p Point) Div(k float64) Point

Div returns the vector p/k.

func (Point) Fixed

func (a Point) Fixed() fixed.Point26_6

func (Point) Lerp

func (a Point) Lerp(other Point, t float64) Point

Lerp Linear interpolates points

func (Point) Mul

func (p Point) Mul(factor Point) Point

Mul returns xy * Point.

func (Point) Rotate

func (a Point) Rotate(angle float64, o Point) Point

Rotate rotates point about origin o

func (Point) Sub

func (p Point) Sub(q Point) Point

Sub returns the vector p-q.

type Style

type Style struct {
	Fill      color.Color
	Stroke    color.Color
	LineWidth float64
	// Line cap style constant
	//
	// 0=ButtCap 1=SquareCap 2=RoundCap 3=CubicCap 4=QuadraticCap
	Cap CapMode
	// Line join style
	//
	// 0=MiterJoin 1=RoundJoin 2=BevelJoin
	Join JoinMode
}

Style of path

Example
package main

import (
	"fmt"
	"image/color"

	"github.com/setanarut/gog"
)

func main() {
	myStyle := gog.NewStyle(color.RGBA{255, 0, 0, 255},
		color.Gray{128}, 10, gog.RoundCap, gog.RoundJoin)
	myStyle2 := gog.Style{
		Fill:      color.RGBA{255, 255, 0, 255},
		Stroke:    color.RGBA{255, 0, 255, 255},
		LineWidth: 7,
		Cap:       gog.CubicCap,
		Join:      gog.BevelJoin,
	}
	square := gog.Square(gog.P(10, 10), 50).SetStyle(myStyle)
	square2 := gog.Square(gog.P(10, 10), 50)
	square2.Style = myStyle2
	square2.SetFill(color.RGBA{0, 255, 255, 255})
	fmt.Printf("%+v\n%+v", square.Style, square2.Style)
}
Output:

{Fill:{R:255 G:0 B:0 A:255} Stroke:{Y:128} LineWidth:10 Cap:2 Join:1}
{Fill:{R:0 G:255 B:255 A:255} Stroke:{R:255 G:0 B:255 A:255} LineWidth:7 Cap:3 Join:2}

func DefaultStyle

func DefaultStyle() Style

DefaultStyle returns default style

func NewStyle

func NewStyle(fill, stroke color.Color, lineWidth float64, cap CapMode, join JoinMode) Style

NewStyle shorthand for create Style{}

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL