refactor transform module
This commit is contained in:
parent
ae9b990671
commit
5e6aa57cf2
3 changed files with 48 additions and 72 deletions
|
@ -446,7 +446,7 @@ func TestTransform() {
|
||||||
|
|
||||||
gc.Save()
|
gc.Save()
|
||||||
gc.Translate(100, 150) // Translate origin to (100, 150)
|
gc.Translate(100, 150) // Translate origin to (100, 150)
|
||||||
gc.Rotate(30* (math.Pi / 180.0)) // Rotate counter-clockwise by 30 degrees
|
gc.Rotate(30* (math.Pi / 180.0)) // Rotate counter-clockwise by 30 degrees
|
||||||
gc.BeginPath()
|
gc.BeginPath()
|
||||||
gc.MoveTo(0,0)
|
gc.MoveTo(0,0)
|
||||||
gc.RLineTo(72,0)
|
gc.RLineTo(72,0)
|
||||||
|
@ -467,10 +467,10 @@ func TestTransform() {
|
||||||
gc.ClosePath() // Draw box...
|
gc.ClosePath() // Draw box...
|
||||||
gc.Stroke()
|
gc.Stroke()
|
||||||
gc.Restore()
|
gc.Restore()
|
||||||
|
|
||||||
gc.Save()
|
gc.Save()
|
||||||
gc.Translate(300, 300) // Set origin to (300, 300)
|
gc.Translate(300, 300) // Set origin to (300, 300)
|
||||||
gc.Rotate(45* (math.Pi / 180.0)) // Rotate coordinates by 45 degrees
|
gc.Rotate(45* (math.Pi / 180.0)) // Rotate coordinates by 45 degrees
|
||||||
gc.Scale(0.5, 1) // Scale coordinates
|
gc.Scale(0.5, 1) // Scale coordinates
|
||||||
gc.BeginPath()
|
gc.BeginPath()
|
||||||
gc.MoveTo(0,0)
|
gc.MoveTo(0,0)
|
||||||
|
|
|
@ -6,6 +6,7 @@ package draw2d
|
||||||
import (
|
import (
|
||||||
"exp/draw"
|
"exp/draw"
|
||||||
"image"
|
"image"
|
||||||
|
//"math"
|
||||||
"freetype-go.googlecode.com/hg/freetype/raster"
|
"freetype-go.googlecode.com/hg/freetype/raster"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -79,28 +80,19 @@ func (gc *GraphicContext) SetMatrixTransform(tr MatrixTransform) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) ComposeMatrixTransform(tr MatrixTransform) {
|
func (gc *GraphicContext) ComposeMatrixTransform(tr MatrixTransform) {
|
||||||
gc.current.tr.Compose(tr)
|
gc.current.tr = tr.Multiply(gc.current.tr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) Rotate(angle float) {
|
func (gc *GraphicContext) Rotate(angle float) {
|
||||||
ox, oy := gc.current.path.LastPoint()
|
gc.current.tr.Rotate(angle)
|
||||||
tr := NewTranslationMatrix(ox, oy)
|
|
||||||
tr2 := NewRotationMatrix(angle)
|
|
||||||
tr1 := tr.GetInverseTransformation()
|
|
||||||
gc.current.tr.Compose(tr).Compose(tr2).Compose(tr1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) Translate(tx, ty float) {
|
func (gc *GraphicContext) Translate(tx, ty float) {
|
||||||
tr := NewTranslationMatrix(tx, ty)
|
gc.current.tr.Translate(tx, ty)
|
||||||
gc.current.tr.Compose(tr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) Scale(sx, sy float) {
|
func (gc *GraphicContext) Scale(sx, sy float) {
|
||||||
ox, oy := gc.current.path.LastPoint()
|
gc.current.tr.Scale(sx, sy)
|
||||||
tr := NewTranslationMatrix(ox, oy)
|
|
||||||
tr2 := NewScaleMatrix(sx, sy)
|
|
||||||
tr1 := tr.GetInverseTransformation()
|
|
||||||
gc.current.tr.Compose(tr).Compose(tr2).Compose(tr1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) Clear() {
|
func (gc *GraphicContext) Clear() {
|
||||||
|
|
|
@ -9,36 +9,19 @@ const (
|
||||||
epsilon = 1e-6
|
epsilon = 1e-6
|
||||||
)
|
)
|
||||||
|
|
||||||
func (tr MatrixTransform) TransformX(x, y float) float {
|
|
||||||
return x*tr[0] + y*tr[2] + tr[4]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tr MatrixTransform) TransformY(x, y float) float {
|
|
||||||
return x*tr[1] + y*tr[3] + tr[5]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tr MatrixTransform) Determinant() float {
|
func (tr MatrixTransform) Determinant() float {
|
||||||
return tr[0]*tr[3] - tr[1]*tr[2]
|
return tr[0]*tr[3] - tr[1]*tr[2]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr MatrixTransform) InverseTransformX(x, y float) float {
|
|
||||||
return ((x-tr[4])*tr[3] - (y-tr[5])*tr[2]) / tr.Determinant()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tr MatrixTransform) InverseTransformY(x, y float) float {
|
|
||||||
return ((y-tr[5])*tr[0] - (x-tr[4])*tr[1]) / tr.Determinant()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tr MatrixTransform) Transform(points ...*float) {
|
func (tr MatrixTransform) Transform(points ...*float) {
|
||||||
for i, j := 0, 1; j < len(points); i, j = i+2, j+2 {
|
for i, j := 0, 1; j < len(points); i, j = i+2, j+2 {
|
||||||
x := *points[i]
|
x := *points[i]
|
||||||
y := *points[j]
|
y := *points[j]
|
||||||
*points[i] = tr.TransformX(x, y)
|
*points[i] = x*tr[0] + y*tr[2] + tr[4]
|
||||||
*points[j] = tr.TransformY(x, y)
|
*points[j] = x*tr[1] + y*tr[3] + tr[5]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (tr MatrixTransform) InverseTransform(points ...*float) {
|
func (tr MatrixTransform) InverseTransform(points ...*float) {
|
||||||
d := tr.Determinant() // matrix determinant
|
d := tr.Determinant() // matrix determinant
|
||||||
for i, j := 0, 1; j < len(points); i, j = i+2, j+2 {
|
for i, j := 0, 1; j < len(points); i, j = i+2, j+2 {
|
||||||
|
@ -51,30 +34,12 @@ func (tr MatrixTransform) InverseTransform(points ...*float) {
|
||||||
|
|
||||||
// ******************** Vector transformations ********************
|
// ******************** Vector transformations ********************
|
||||||
|
|
||||||
func (tr MatrixTransform) VectorTransformX(x, y float) float {
|
|
||||||
return x*tr[0] + y*tr[2]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tr MatrixTransform) VectorTransformY(x, y float) float {
|
|
||||||
return x*tr[1] + y*tr[3]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tr MatrixTransform) VectorInverseTransformX(x, y float) float {
|
|
||||||
d := tr.Determinant() // matrix determinant
|
|
||||||
return (x*tr[3] - y*tr[2]) / d
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tr MatrixTransform) VectorInverseTransformY(x, y float) float {
|
|
||||||
d := tr.Determinant() // matrix determinant
|
|
||||||
return (y*tr[0] - x*tr[1]) / d
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tr MatrixTransform) VectorTransform(points ...*float) {
|
func (tr MatrixTransform) VectorTransform(points ...*float) {
|
||||||
for i, j := 0, 1; j < len(points); i, j = i+2, j+2 {
|
for i, j := 0, 1; j < len(points); i, j = i+2, j+2 {
|
||||||
x := *points[i]
|
x := *points[i]
|
||||||
y := *points[j]
|
y := *points[j]
|
||||||
*points[i] = tr.VectorTransformX(x, y)
|
*points[i] = x*tr[0] + y*tr[2]
|
||||||
*points[j] = tr.VectorTransformY(x, y)
|
*points[j] = x*tr[1] + y*tr[3]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +77,7 @@ func NewRotationMatrix(angle float) MatrixTransform {
|
||||||
/**
|
/**
|
||||||
* Creates a transformation, combining a scale and a translation, that transform rectangle1 into rectangle2.
|
* Creates a transformation, combining a scale and a translation, that transform rectangle1 into rectangle2.
|
||||||
*/
|
*/
|
||||||
func NewMatrixTransform(rectangle1 [4]float, rectangle2 [4]float) MatrixTransform {
|
func NewMatrixTransform(rectangle1, rectangle2 [4]float) MatrixTransform {
|
||||||
xScale := (rectangle2[2] - rectangle2[0]) / (rectangle1[2] - rectangle1[0])
|
xScale := (rectangle2[2] - rectangle2[0]) / (rectangle1[2] - rectangle1[0])
|
||||||
yScale := (rectangle2[3] - rectangle2[1]) / (rectangle1[3] - rectangle1[1])
|
yScale := (rectangle2[3] - rectangle2[1]) / (rectangle1[3] - rectangle1[1])
|
||||||
xOffset := rectangle2[0] - (rectangle1[0] * xScale)
|
xOffset := rectangle2[0] - (rectangle1[0] * xScale)
|
||||||
|
@ -136,15 +101,8 @@ func (tr MatrixTransform) GetInverseTransformation() MatrixTransform {
|
||||||
(tr[1]*tr[4] - tr[0]*tr[5]) / d}
|
(tr[1]*tr[4] - tr[0]*tr[5]) / d}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a transformation that is the composition (tr2 o tr1) of the given
|
|
||||||
* transformations tr2 and tr1.
|
|
||||||
|
|
||||||
* For given point (x, y), the composed transformation is defined by the
|
func (tr1 MatrixTransform) Multiply(tr2 MatrixTransform) MatrixTransform {
|
||||||
* equation:
|
|
||||||
* (tr2 o tr1)(x, y) = tr2(tr1(x, y))
|
|
||||||
*/
|
|
||||||
func (tr1 MatrixTransform) GetComposedTransformation(tr2 MatrixTransform) MatrixTransform {
|
|
||||||
return [6]float{
|
return [6]float{
|
||||||
tr1[0]*tr2[0] + tr1[1]*tr2[2],
|
tr1[0]*tr2[0] + tr1[1]*tr2[2],
|
||||||
tr1[1]*tr2[3] + tr1[0]*tr2[1],
|
tr1[1]*tr2[3] + tr1[0]*tr2[1],
|
||||||
|
@ -154,14 +112,40 @@ func (tr1 MatrixTransform) GetComposedTransformation(tr2 MatrixTransform) Matrix
|
||||||
tr1[5]*tr2[3] + tr1[4]*tr2[1] + tr2[5]}
|
tr1[5]*tr2[3] + tr1[4]*tr2[1] + tr2[5]}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr1 *MatrixTransform) Compose(tr2 MatrixTransform) (*MatrixTransform){
|
|
||||||
tr1[0] = tr2[0]*tr1[0] + tr2[1]*tr1[2]
|
func (tr *MatrixTransform) Scale(sx, sy float) (*MatrixTransform){
|
||||||
tr1[1] = tr2[1]*tr1[3] + tr2[0]*tr1[1]
|
tr[0] = tr[0]*sx;
|
||||||
tr1[2] = tr2[2]*tr1[0] + tr2[3]*tr1[2]
|
tr[1] = tr[1]*sx;
|
||||||
tr1[3] = tr2[3]*tr1[3] + tr2[2]*tr1[1]
|
tr[4] = tr[4]*sx;
|
||||||
tr1[4] = tr2[4]*tr1[0] + tr2[5]*tr1[2] + tr1[4]
|
tr[2] = tr[2]*sy;
|
||||||
tr1[5] = tr2[5]*tr1[3] + tr2[4]*tr1[1] + tr1[5]
|
tr[3] = tr[3]*sy;
|
||||||
return tr1
|
tr[5] = tr[5]*sy;
|
||||||
|
return tr;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tr *MatrixTransform) Translate(tx, ty float) (*MatrixTransform){
|
||||||
|
tr[4] = tr[4] + tx
|
||||||
|
tr[5] = tr[5] + ty
|
||||||
|
return tr;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tr *MatrixTransform) Rotate(angle float) (*MatrixTransform){
|
||||||
|
ca := cos(angle);
|
||||||
|
sa := sin(angle);
|
||||||
|
t0 := tr[0] * ca - tr[1] * sa;
|
||||||
|
t2 := tr[1] * ca - tr[3] * sa;
|
||||||
|
t4 := tr[4] * ca - tr[5] * sa;
|
||||||
|
tr[1] = tr[0] * sa + tr[1] * ca;
|
||||||
|
tr[3] = tr[2] * sa + tr[3] * ca;
|
||||||
|
tr[5] = tr[4] * sa + tr[5] * ca;
|
||||||
|
tr[0] = t0;
|
||||||
|
tr[2] = t2;
|
||||||
|
tr[4] = t4;
|
||||||
|
return tr;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tr MatrixTransform) GetTranslation() (x, y float) {
|
||||||
|
return tr[4], tr[5]
|
||||||
}
|
}
|
||||||
|
|
||||||
// ******************** Testing ********************
|
// ******************** Testing ********************
|
||||||
|
|
Loading…
Reference in a new issue