Matrix, WritePNG, Ellipse example
This commit is contained in:
parent
cabeb41b27
commit
be8bb502f3
41
context.go
41
context.go
@ -46,6 +46,7 @@ type Context struct {
|
||||
lineJoin LineJoin
|
||||
fillRule FillRule
|
||||
fontFace font.Face
|
||||
matrix Matrix
|
||||
}
|
||||
|
||||
func NewContext(width, height int) *Context {
|
||||
@ -65,6 +66,7 @@ func NewContextForRGBA(im *image.RGBA) *Context {
|
||||
lineWidth: 1,
|
||||
fillRule: FillRuleWinding,
|
||||
fontFace: basicfont.Face7x13,
|
||||
matrix: Identity(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,8 +82,8 @@ func (dc *Context) Height() int {
|
||||
return dc.height
|
||||
}
|
||||
|
||||
func (dc *Context) WriteToPNG(path string) error {
|
||||
return writeToPNG(path, dc.im)
|
||||
func (dc *Context) WritePNG(path string) error {
|
||||
return writePNG(path, dc.im)
|
||||
}
|
||||
|
||||
func (dc *Context) SetLineWidth(lineWidth float64) {
|
||||
@ -163,11 +165,13 @@ func (dc *Context) SetRGB(r, g, b float64) {
|
||||
// Path Manipulation
|
||||
|
||||
func (dc *Context) MoveTo(x, y float64) {
|
||||
x, y = dc.TransformPoint(x, y)
|
||||
dc.start = fp(x, y)
|
||||
dc.path.Start(dc.start)
|
||||
}
|
||||
|
||||
func (dc *Context) LineTo(x, y float64) {
|
||||
x, y = dc.TransformPoint(x, y)
|
||||
if len(dc.path) == 0 {
|
||||
dc.MoveTo(x, y)
|
||||
} else {
|
||||
@ -176,6 +180,8 @@ func (dc *Context) LineTo(x, y float64) {
|
||||
}
|
||||
|
||||
func (dc *Context) QuadraticTo(x1, y1, x2, y2 float64) {
|
||||
x1, y1 = dc.TransformPoint(x1, y1)
|
||||
x2, y2 = dc.TransformPoint(x2, y2)
|
||||
if len(dc.path) == 0 {
|
||||
dc.MoveTo(x1, y1)
|
||||
} else {
|
||||
@ -307,6 +313,7 @@ func (dc *Context) LoadFontFace(path string, size float64) {
|
||||
}
|
||||
|
||||
func (dc *Context) DrawString(x, y float64, s string) {
|
||||
x, y = dc.TransformPoint(x, y)
|
||||
d := &font.Drawer{
|
||||
Dst: dc.im,
|
||||
Src: image.NewUniform(dc.color),
|
||||
@ -325,3 +332,33 @@ func (dc *Context) MeasureString(s string) float64 {
|
||||
a := d.MeasureString(s)
|
||||
return float64(a >> 6)
|
||||
}
|
||||
|
||||
// Transformation Matrix Operations
|
||||
|
||||
func (dc *Context) Identity() {
|
||||
dc.matrix = Identity()
|
||||
}
|
||||
|
||||
func (dc *Context) Translate(x, y float64) {
|
||||
dc.matrix = dc.matrix.Translate(x, y)
|
||||
}
|
||||
|
||||
func (dc *Context) Scale(x, y float64) {
|
||||
dc.matrix = dc.matrix.Scale(x, y)
|
||||
}
|
||||
|
||||
func (dc *Context) Rotate(angle float64) {
|
||||
dc.matrix = dc.matrix.Rotate(angle)
|
||||
}
|
||||
|
||||
func (dc *Context) RotateAbout(angle, x, y float64) {
|
||||
dc.matrix = dc.matrix.RotateAbout(angle, x, y)
|
||||
}
|
||||
|
||||
func (dc *Context) Shear(x, y float64) {
|
||||
dc.matrix = dc.matrix.Shear(x, y)
|
||||
}
|
||||
|
||||
func (dc *Context) TransformPoint(x, y float64) (tx, ty float64) {
|
||||
return dc.matrix.TransformPoint(x, y)
|
||||
}
|
||||
|
@ -12,5 +12,5 @@ func main() {
|
||||
dc.SetRGB(0, 0, 0.5)
|
||||
dc.SetLineWidth(8)
|
||||
dc.Stroke()
|
||||
dc.WriteToPNG("out.png")
|
||||
dc.WritePNG("out.png")
|
||||
}
|
||||
|
18
examples/ellipse.go
Normal file
18
examples/ellipse.go
Normal file
@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
import "github.com/fogleman/gg"
|
||||
|
||||
func main() {
|
||||
const S = 1024
|
||||
dc := gg.NewContext(S, S)
|
||||
dc.SetRGB(1, 1, 1)
|
||||
dc.Clear()
|
||||
for i := 0; i < 360; i += 15 {
|
||||
dc.Identity()
|
||||
dc.RotateAbout(gg.Radians(float64(i)), S/2, S/2)
|
||||
dc.DrawEllipse(S/2, S/2, S*7/16, S/8)
|
||||
dc.SetRGBA(0, 0, 0, 0.1)
|
||||
dc.Fill()
|
||||
}
|
||||
dc.WritePNG("out.png")
|
||||
}
|
@ -16,5 +16,5 @@ func main() {
|
||||
dc.SetRGB(0, 0, 0)
|
||||
dc.SetLineWidth(8)
|
||||
dc.Stroke()
|
||||
dc.WriteToPNG("out.png")
|
||||
dc.WritePNG("out.png")
|
||||
}
|
||||
|
@ -27,5 +27,5 @@ func main() {
|
||||
dc.DrawLine(x1, y1, x2, y2)
|
||||
dc.Stroke()
|
||||
}
|
||||
dc.WriteToPNG("out.png")
|
||||
dc.WritePNG("out.png")
|
||||
}
|
||||
|
@ -36,5 +36,5 @@ func main() {
|
||||
dc.SetRGBA(0, 1, 0, 0.5)
|
||||
dc.SetLineWidth(16)
|
||||
dc.Stroke()
|
||||
dc.WriteToPNG("out.png")
|
||||
dc.WritePNG("out.png")
|
||||
}
|
||||
|
@ -11,5 +11,5 @@ func main() {
|
||||
s := "Hello, world!"
|
||||
w := dc.MeasureString(s)
|
||||
dc.DrawString(500-w/2, 500, s)
|
||||
dc.WriteToPNG("out.png")
|
||||
dc.WritePNG("out.png")
|
||||
}
|
||||
|
99
matrix.go
Normal file
99
matrix.go
Normal file
@ -0,0 +1,99 @@
|
||||
package gg
|
||||
|
||||
import "math"
|
||||
|
||||
type Matrix struct {
|
||||
XX, YX, XY, YY, X0, Y0 float64
|
||||
}
|
||||
|
||||
func Identity() Matrix {
|
||||
return Matrix{
|
||||
1, 0,
|
||||
0, 1,
|
||||
0, 0,
|
||||
}
|
||||
}
|
||||
|
||||
func Translate(x, y float64) Matrix {
|
||||
return Matrix{
|
||||
1, 0,
|
||||
0, 1,
|
||||
x, y,
|
||||
}
|
||||
}
|
||||
|
||||
func Scale(x, y float64) Matrix {
|
||||
return Matrix{
|
||||
x, 0,
|
||||
0, y,
|
||||
0, 0,
|
||||
}
|
||||
}
|
||||
|
||||
func Rotate(angle float64) Matrix {
|
||||
c := math.Cos(angle)
|
||||
s := math.Sin(angle)
|
||||
return Matrix{
|
||||
c, s,
|
||||
-s, c,
|
||||
0, 0,
|
||||
}
|
||||
}
|
||||
|
||||
func RotateAbout(angle, x, y float64) Matrix {
|
||||
a := Translate(x, y)
|
||||
b := Rotate(angle)
|
||||
c := Translate(-x, -y)
|
||||
return c.Multiply(b).Multiply(a)
|
||||
}
|
||||
|
||||
func Shear(x, y float64) Matrix {
|
||||
return Matrix{
|
||||
1, x,
|
||||
y, 1,
|
||||
0, 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (a Matrix) Multiply(b Matrix) Matrix {
|
||||
return Matrix{
|
||||
a.XX*b.XX + a.YX*b.XY,
|
||||
a.XX*b.YX + a.YX*b.YY,
|
||||
a.XY*b.XX + a.YY*b.XY,
|
||||
a.XY*b.YX + a.YY*b.YY,
|
||||
a.X0*b.XX + a.Y0*b.XY + b.X0,
|
||||
a.X0*b.YX + a.Y0*b.YY + b.Y0,
|
||||
}
|
||||
}
|
||||
|
||||
func (a Matrix) TransformVector(x, y float64) (tx, ty float64) {
|
||||
tx = a.XX*x + a.XY*y
|
||||
ty = a.YX*x + a.YY*y
|
||||
return
|
||||
}
|
||||
|
||||
func (a Matrix) TransformPoint(x, y float64) (tx, ty float64) {
|
||||
tx = a.XX*x + a.XY*y + a.X0
|
||||
ty = a.YX*x + a.YY*y + a.Y0
|
||||
return
|
||||
}
|
||||
|
||||
func (a Matrix) Translate(x, y float64) Matrix {
|
||||
return Translate(x, y).Multiply(a)
|
||||
}
|
||||
|
||||
func (a Matrix) Scale(x, y float64) Matrix {
|
||||
return Scale(x, y).Multiply(a)
|
||||
}
|
||||
|
||||
func (a Matrix) Rotate(angle float64) Matrix {
|
||||
return Rotate(angle).Multiply(a)
|
||||
}
|
||||
|
||||
func (a Matrix) RotateAbout(angle, x, y float64) Matrix {
|
||||
return RotateAbout(angle, x, y).Multiply(a)
|
||||
}
|
||||
|
||||
func (a Matrix) Shear(x, y float64) Matrix {
|
||||
return Shear(x, y).Multiply(a)
|
||||
}
|
11
util.go
11
util.go
@ -6,6 +6,7 @@ import (
|
||||
"image/draw"
|
||||
"image/png"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
@ -15,7 +16,15 @@ import (
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
||||
func writeToPNG(path string, im image.Image) error {
|
||||
func Radians(degrees float64) float64 {
|
||||
return degrees * math.Pi / 180
|
||||
}
|
||||
|
||||
func Degrees(radians float64) float64 {
|
||||
return radians * 180 / math.Pi
|
||||
}
|
||||
|
||||
func writePNG(path string, im image.Image) error {
|
||||
file, err := os.Create(path)
|
||||
if err != nil {
|
||||
return err
|
||||
|
Loading…
Reference in New Issue
Block a user