This commit is contained in:
Laurent Le Goff 2015-04-29 18:09:07 +02:00
parent c686a7fcf6
commit c7ef18681a
2 changed files with 29 additions and 45 deletions

16
gc.go
View file

@ -33,21 +33,35 @@ const (
type GraphicContext interface { type GraphicContext interface {
PathBuilder PathBuilder
// Create a new path // BeginPath creates a new path
BeginPath() BeginPath()
// GetMatrixTransform returns the current transformation matrix
GetMatrixTransform() MatrixTransform GetMatrixTransform() MatrixTransform
// SetMatrixTransform sets the current transformation matrix
SetMatrixTransform(tr MatrixTransform) SetMatrixTransform(tr MatrixTransform)
// ComposeMatrixTransform composes the current transformation matrix with tr
ComposeMatrixTransform(tr MatrixTransform) ComposeMatrixTransform(tr MatrixTransform)
// Rotate applies a rotation to the current transformation matrix. angle is in radian.
Rotate(angle float64) Rotate(angle float64)
// Translate applies a translation to the current transformation matrix.
Translate(tx, ty float64) Translate(tx, ty float64)
// Scale applies a scale to the current transformation matrix.
Scale(sx, sy float64) Scale(sx, sy float64)
// SetStrokeColor sets the current stroke color
SetStrokeColor(c color.Color) SetStrokeColor(c color.Color)
// SetStrokeColor sets the current fill color
SetFillColor(c color.Color) SetFillColor(c color.Color)
// SetFillRule sets the current fill rule
SetFillRule(f FillRule) SetFillRule(f FillRule)
// SetLineWidth sets the current line width
SetLineWidth(lineWidth float64) SetLineWidth(lineWidth float64)
// SetLineCap sets the current line cap
SetLineCap(cap LineCap) SetLineCap(cap LineCap)
// SetLineJoin sets the current line join
SetLineJoin(join LineJoin) SetLineJoin(join LineJoin)
// SetLineJoin sets the current dash
SetLineDash(dash []float64, dashOffset float64) SetLineDash(dash []float64, dashOffset float64)
// SetFontSize
SetFontSize(fontSize float64) SetFontSize(fontSize float64)
GetFontSize() float64 GetFontSize() float64
SetFontData(fontData FontData) SetFontData(fontData FontData)

View file

@ -18,7 +18,7 @@ func (tr MatrixTransform) Determinant() float64 {
return tr[0]*tr[3] - tr[1]*tr[2] return tr[0]*tr[3] - tr[1]*tr[2]
} }
// Transform apply the transformation matrix to points. It modify the points passed in parameter. // Transform applies the transformation matrix to points. It modify the points passed in parameter.
func (tr MatrixTransform) Transform(points []float64) { func (tr MatrixTransform) Transform(points []float64) {
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]
@ -28,7 +28,7 @@ func (tr MatrixTransform) Transform(points []float64) {
} }
} }
// TransformPoint apply the transformation matrix to point. It returns the point the transformed point. // TransformPoint applies the transformation matrix to point. It returns the point the transformed point.
func (tr MatrixTransform) TransformPoint(x, y float64) (xres, yres float64) { func (tr MatrixTransform) TransformPoint(x, y float64) (xres, yres float64) {
xres = x*tr[0] + y*tr[2] + tr[4] xres = x*tr[0] + y*tr[2] + tr[4]
yres = x*tr[1] + y*tr[3] + tr[5] yres = x*tr[1] + y*tr[3] + tr[5]
@ -42,7 +42,7 @@ func minMax(x, y float64) (min, max float64) {
return x, y return x, y
} }
// Transform apply the transformation matrix to the rectangle represented by the min and the max point of the rectangle // Transform applies the transformation matrix to the rectangle represented by the min and the max point of the rectangle
func (tr MatrixTransform) TransformRectangle(x0, y0, x2, y2 float64) (nx0, ny0, nx2, ny2 float64) { func (tr MatrixTransform) TransformRectangle(x0, y0, x2, y2 float64) (nx0, ny0, nx2, ny2 float64) {
points := []float64{x0, y0, x2, y0, x2, y2, x0, y2} points := []float64{x0, y0, x2, y0, x2, y2, x0, y2}
tr.Transform(points) tr.Transform(points)
@ -58,7 +58,7 @@ func (tr MatrixTransform) TransformRectangle(x0, y0, x2, y2 float64) (nx0, ny0,
return nx0, ny0, nx2, ny2 return nx0, ny0, nx2, ny2
} }
// InverseTransform apply the transformation inverse matrix to the rectangle represented by the min and the max point of the rectangle // InverseTransform applies the transformation inverse matrix to the rectangle represented by the min and the max point of the rectangle
func (tr MatrixTransform) InverseTransform(points []float64) { func (tr MatrixTransform) InverseTransform(points []float64) {
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 {
@ -69,7 +69,7 @@ func (tr MatrixTransform) InverseTransform(points []float64) {
} }
} }
// InverseTransformPoint apply the transformation inverse matrix to point. It returns the point the transformed point. // InverseTransformPoint applies the transformation inverse matrix to point. It returns the point the transformed point.
func (tr MatrixTransform) InverseTransformPoint(x, y float64) (xres, yres float64) { func (tr MatrixTransform) InverseTransformPoint(x, y float64) (xres, yres float64) {
d := tr.Determinant() // matrix determinant d := tr.Determinant() // matrix determinant
xres = ((x-tr[4])*tr[3] - (y-tr[5])*tr[2]) / d xres = ((x-tr[4])*tr[3] - (y-tr[5])*tr[2]) / d
@ -77,7 +77,7 @@ func (tr MatrixTransform) InverseTransformPoint(x, y float64) (xres, yres float6
return xres, yres return xres, yres
} }
// VectorTransform apply the transformation matrix to points without using the translation parameter of the affine matrix. // VectorTransform applies the transformation matrix to points without using the translation parameter of the affine matrix.
// It modify the points passed in parameter. // It modify the points passed in parameter.
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 { for i, j := 0, 1; j < len(points); i, j = i+2, j+2 {
@ -131,7 +131,7 @@ func (tr MatrixTransform) Inverse() MatrixTransform {
(tr[1]*tr[4] - tr[0]*tr[5]) / d} (tr[1]*tr[4] - tr[0]*tr[5]) / d}
} }
// Multiply Compose Matrix tr1 with tr2 returns the resulting matrix // Multiply composes Matrix tr1 with tr2 returns the resulting matrix
func (tr1 MatrixTransform) Multiply(tr2 MatrixTransform) MatrixTransform { func (tr1 MatrixTransform) Multiply(tr2 MatrixTransform) MatrixTransform {
return [6]float64{ return [6]float64{
tr1[0]*tr2[0] + tr1[1]*tr2[2], tr1[0]*tr2[0] + tr1[1]*tr2[2],
@ -142,7 +142,7 @@ func (tr1 MatrixTransform) Multiply(tr2 MatrixTransform) MatrixTransform {
tr1[5]*tr2[3] + tr1[4]*tr2[1] + tr2[5]} tr1[5]*tr2[3] + tr1[4]*tr2[1] + tr2[5]}
} }
// Scale add a scale to the matrix // Scale adds a scale to the matrix
func (tr *MatrixTransform) Scale(sx, sy float64) *MatrixTransform { func (tr *MatrixTransform) Scale(sx, sy float64) *MatrixTransform {
tr[0] = sx * tr[0] tr[0] = sx * tr[0]
tr[1] = sx * tr[1] tr[1] = sx * tr[1]
@ -151,14 +151,14 @@ func (tr *MatrixTransform) Scale(sx, sy float64) *MatrixTransform {
return tr return tr
} }
// Translate add a translation to the matrix // Translate adds a translation to the matrix
func (tr *MatrixTransform) Translate(tx, ty float64) *MatrixTransform { func (tr *MatrixTransform) Translate(tx, ty float64) *MatrixTransform {
tr[4] = tx*tr[0] + ty*tr[2] + tr[4] tr[4] = tx*tr[0] + ty*tr[2] + tr[4]
tr[5] = ty*tr[3] + tx*tr[1] + tr[5] tr[5] = ty*tr[3] + tx*tr[1] + tr[5]
return tr return tr
} }
// Rotate add a rotation to the matrix. angle is in radian // Rotate adds a rotation to the matrix. angle is in radian
func (tr *MatrixTransform) Rotate(angle float64) *MatrixTransform { func (tr *MatrixTransform) Rotate(angle float64) *MatrixTransform {
c := math.Cos(angle) c := math.Cos(angle)
s := math.Sin(angle) s := math.Sin(angle)
@ -190,30 +190,9 @@ func (tr MatrixTransform) GetScale() float64 {
return math.Sqrt(x*x + y*y) return math.Sqrt(x*x + y*y)
} }
func (tr MatrixTransform) GetMaxAbsScaling() (s float64) {
sx := math.Abs(tr[0])
sy := math.Abs(tr[3])
if sx > sy {
return sx
}
return sy
}
func (tr MatrixTransform) GetMinAbsScaling() (s float64) {
sx := math.Abs(tr[0])
sy := math.Abs(tr[3])
if sx > sy {
return sy
}
return sx
}
// ******************** Testing ******************** // ******************** Testing ********************
/** // Equals tests if a two transformation are equal. A tolerance is applied when comparing matrix elements.
* Tests if a two transformation are equal. A tolerance is applied when
* comparing matrix elements.
*/
func (tr1 MatrixTransform) Equals(tr2 MatrixTransform) bool { func (tr1 MatrixTransform) Equals(tr2 MatrixTransform) bool {
for i := 0; i < 6; i = i + 1 { for i := 0; i < 6; i = i + 1 {
if !fequals(tr1[i], tr2[i]) { if !fequals(tr1[i], tr2[i]) {
@ -223,26 +202,17 @@ func (tr1 MatrixTransform) Equals(tr2 MatrixTransform) bool {
return true return true
} }
/** // IsIdentity tests if a transformation is the identity transformation. A tolerance is applied when comparing matrix elements.
* Tests if a transformation is the identity transformation. A tolerance
* is applied when comparing matrix elements.
*/
func (tr MatrixTransform) IsIdentity() bool { func (tr MatrixTransform) IsIdentity() bool {
return fequals(tr[4], 0) && fequals(tr[5], 0) && tr.IsTranslation() return fequals(tr[4], 0) && fequals(tr[5], 0) && tr.IsTranslation()
} }
/** // IsTranslation tests if a transformation is is a pure translation. A tolerance is applied when comparing matrix elements.
* Tests if a transformation is is a pure translation. A tolerance
* is applied when comparing matrix elements.
*/
func (tr MatrixTransform) IsTranslation() bool { func (tr MatrixTransform) IsTranslation() bool {
return fequals(tr[0], 1) && fequals(tr[1], 0) && fequals(tr[2], 0) && fequals(tr[3], 1) return fequals(tr[0], 1) && fequals(tr[1], 0) && fequals(tr[2], 0) && fequals(tr[3], 1)
} }
/** // fequals compares two floats. return true if the distance between the two floats is less than epsilon, false otherwise
* Compares two floats.
* return true if the distance between the two floats is less than epsilon, false otherwise
*/
func fequals(float1, float2 float64) bool { func fequals(float1, float2 float64) bool {
return math.Abs(float1-float2) <= epsilon return math.Abs(float1-float2) <= epsilon
} }