clean Transform

This commit is contained in:
Laurent Le Goff 2015-04-29 16:19:49 +02:00
parent 966a9b73f7
commit 511954196b
2 changed files with 39 additions and 78 deletions

View file

@ -107,8 +107,7 @@ func cubic(offset, v0, v1, v2, v3 float64) uint32 {
func DrawImage(src image.Image, dest draw.Image, tr draw2d.MatrixTransform, op draw.Op, filter ImageFilter) {
bounds := src.Bounds()
x0, y0, x1, y1 := float64(bounds.Min.X), float64(bounds.Min.Y), float64(bounds.Max.X), float64(bounds.Max.Y)
tr.TransformRectangle(&x0, &y0, &x1, &y1)
x0, y0, x1, y1 := tr.TransformRectangle(float64(bounds.Min.X), float64(bounds.Min.Y), float64(bounds.Max.X), float64(bounds.Max.Y))
var x, y, u, v float64
var c1, c2, cr color.Color
var r, g, b, a, ia, r1, g1, b1, a1, r2, g2, b2, a2 uint32
@ -117,7 +116,7 @@ func DrawImage(src image.Image, dest draw.Image, tr draw2d.MatrixTransform, op d
for y = y0; y < y1; y++ {
u = x
v = y
tr.InverseTransform(&u, &v)
u, v = tr.InverseTransformPoint(u, v)
if bounds.Min.X <= int(u) && bounds.Max.X > int(u) && bounds.Min.Y <= int(v) && bounds.Max.Y > int(v) {
c1 = dest.At(int(x), int(y))
switch filter {

View file

@ -5,8 +5,6 @@ package draw2d
import (
"math"
"code.google.com/p/freetype-go/freetype/raster"
)
type MatrixTransform [6]float64
@ -19,16 +17,8 @@ func (tr MatrixTransform) Determinant() float64 {
return tr[0]*tr[3] - tr[1]*tr[2]
}
func (tr MatrixTransform) Transform(points ...*float64) {
for i, j := 0, 1; j < len(points); i, j = i+2, j+2 {
x := *points[i]
y := *points[j]
*points[i] = x*tr[0] + y*tr[2] + tr[4]
*points[j] = x*tr[1] + y*tr[3] + tr[5]
}
}
func (tr MatrixTransform) TransformArray(points []float64) {
// Transform apply the Affine Matrix to points. It modify the points passed in parameter.
func (tr MatrixTransform) Transform(points []float64) {
for i, j := 0, 1; j < len(points); i, j = i+2, j+2 {
x := points[i]
y := points[j]
@ -37,6 +27,12 @@ func (tr MatrixTransform) TransformArray(points []float64) {
}
}
func (tr MatrixTransform) TransformPoint(x, y float64) (xres, yres float64) {
xres = x*tr[0] + y*tr[2] + tr[4]
yres = x*tr[1] + y*tr[3] + tr[5]
return xres, yres
}
func minMax(x, y float64) (min, max float64) {
if x > y {
return y, x
@ -44,50 +40,46 @@ func minMax(x, y float64) (min, max float64) {
return x, y
}
func (tr MatrixTransform) TransformRectangle(x0, y0, x2, y2 *float64) {
x1 := *x2
y1 := *y0
x3 := *x0
y3 := *y2
tr.Transform(x0, y0, &x1, &y1, x2, y2, &x3, &y3)
*x0, x1 = minMax(*x0, x1)
*x2, x3 = minMax(*x2, x3)
*y0, y1 = minMax(*y0, y1)
*y2, y3 = minMax(*y2, y3)
func (tr MatrixTransform) TransformRectangle(x0, y0, x2, y2 float64) (nx0, ny0, nx2, ny2 float64) {
points := []float64{x0, y0, x2, y0, x2, y2, x0, y2}
tr.Transform(points)
points[0], points[2] = minMax(points[0], points[2])
points[4], points[6] = minMax(points[4], points[6])
points[1], points[3] = minMax(points[1], points[3])
points[5], points[7] = minMax(points[5], points[7])
*x0 = math.Min(*x0, *x2)
*y0 = math.Min(*y0, *y2)
*x2 = math.Max(x1, x3)
*y2 = math.Max(y1, y3)
nx0 = math.Min(points[0], points[4])
ny0 = math.Min(points[1], points[5])
nx2 = math.Max(points[2], points[6])
ny2 = math.Max(points[3], points[7])
return nx0, ny0, nx2, ny2
}
func (tr MatrixTransform) TransformRasterPoint(points ...*raster.Point) {
for _, point := range points {
x := float64(point.X) / 256
y := float64(point.Y) / 256
point.X = raster.Fix32((x*tr[0] + y*tr[2] + tr[4]) * 256)
point.Y = raster.Fix32((x*tr[1] + y*tr[3] + tr[5]) * 256)
}
}
func (tr MatrixTransform) InverseTransform(points ...*float64) {
func (tr MatrixTransform) InverseTransform(points []float64) {
d := tr.Determinant() // matrix determinant
for i, j := 0, 1; j < len(points); i, j = i+2, j+2 {
x := *points[i]
y := *points[j]
*points[i] = ((x-tr[4])*tr[3] - (y-tr[5])*tr[2]) / d
*points[j] = ((y-tr[5])*tr[0] - (x-tr[4])*tr[1]) / d
x := points[i]
y := points[j]
points[i] = ((x-tr[4])*tr[3] - (y-tr[5])*tr[2]) / d
points[j] = ((y-tr[5])*tr[0] - (x-tr[4])*tr[1]) / d
}
}
func (tr MatrixTransform) InverseTransformPoint(x, y float64) (xres, yres float64) {
d := tr.Determinant() // matrix determinant
xres = ((x-tr[4])*tr[3] - (y-tr[5])*tr[2]) / d
yres = ((y-tr[5])*tr[0] - (x-tr[4])*tr[1]) / d
return xres, yres
}
// ******************** Vector transformations ********************
func (tr MatrixTransform) VectorTransform(points ...*float64) {
func (tr MatrixTransform) VectorTransform(points []float64) {
for i, j := 0, 1; j < len(points); i, j = i+2, j+2 {
x := *points[i]
y := *points[j]
*points[i] = x*tr[0] + y*tr[2]
*points[j] = x*tr[1] + y*tr[3]
x := points[i]
y := points[j]
points[i] = x*tr[0] + y*tr[2]
points[j] = x*tr[1] + y*tr[3]
}
}
@ -287,33 +279,3 @@ func (t Transformer) Close() {
func (t Transformer) End() {
t.Flattener.End()
}
// this adder apply a Matrix transformation to points
type MatrixTransformAdder struct {
tr MatrixTransform
next raster.Adder
}
// Start starts a new curve at the given point.
func (mta MatrixTransformAdder) Start(a raster.Point) {
mta.tr.TransformRasterPoint(&a)
mta.next.Start(a)
}
// Add1 adds a linear segment to the current curve.
func (mta MatrixTransformAdder) Add1(b raster.Point) {
mta.tr.TransformRasterPoint(&b)
mta.next.Add1(b)
}
// Add2 adds a quadratic segment to the current curve.
func (mta MatrixTransformAdder) Add2(b, c raster.Point) {
mta.tr.TransformRasterPoint(&b, &c)
mta.next.Add2(b, c)
}
// Add3 adds a cubic segment to the current curve.
func (mta MatrixTransformAdder) Add3(b, c, d raster.Point) {
mta.tr.TransformRasterPoint(&b, &c, &d)
mta.next.Add3(b, c, d)
}