replace all reference of float to float64
now works with last version of go
This commit is contained in:
parent
42e131c796
commit
c76a3b7eac
19 changed files with 206 additions and 235 deletions
|
@ -11,8 +11,8 @@ import (
|
||||||
|
|
||||||
"image"
|
"image"
|
||||||
"image/png"
|
"image/png"
|
||||||
"draw2d"
|
//"draw2d"
|
||||||
//"draw2d.googlecode.com/svn/trunk/draw2d/src/pkg/draw2d"
|
"draw2d.googlecode.com/svn/trunk/draw2d/src/pkg/draw2d"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,9 +47,9 @@ func main() {
|
||||||
case draw.MouseEvent:
|
case draw.MouseEvent:
|
||||||
if evt.Buttons&1 != 0 {
|
if evt.Buttons&1 != 0 {
|
||||||
if nbclick%2 == 0 {
|
if nbclick%2 == 0 {
|
||||||
gc.MoveTo(float(evt.Loc.X), float(evt.Loc.Y))
|
gc.MoveTo(float64(evt.Loc.X), float64(evt.Loc.Y))
|
||||||
} else {
|
} else {
|
||||||
gc.LineTo(float(evt.Loc.X), float(evt.Loc.Y))
|
gc.LineTo(float64(evt.Loc.X), float64(evt.Loc.Y))
|
||||||
gc.Stroke()
|
gc.Stroke()
|
||||||
window.FlushImage()
|
window.FlushImage()
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ func initGc(w, h int) (image.Image, *draw2d.GraphicContext) {
|
||||||
|
|
||||||
func saveToPngFile(TestName string, m image.Image) {
|
func saveToPngFile(TestName string, m image.Image) {
|
||||||
dt := time.Nanoseconds() - lastTime
|
dt := time.Nanoseconds() - lastTime
|
||||||
fmt.Printf("%s during: %f ms\n", TestName, float(dt)*10e-6)
|
fmt.Printf("%s during: %f ms\n", TestName, float64(dt)*10e-6)
|
||||||
filePath := folder + TestName + ".png"
|
filePath := folder + TestName + ".png"
|
||||||
f, err := os.Open(filePath, os.O_CREAT|os.O_WRONLY, 0600)
|
f, err := os.Open(filePath, os.O_CREAT|os.O_WRONLY, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -61,7 +61,7 @@ func saveToPngFile(TestName string, m image.Image) {
|
||||||
fmt.Printf("Wrote %s OK.\n", filePath)
|
fmt.Printf("Wrote %s OK.\n", filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func android(gc *draw2d.GraphicContext, x, y float) {
|
func android(gc *draw2d.GraphicContext, x, y float64) {
|
||||||
gc.SetLineCap(draw2d.RoundCap)
|
gc.SetLineCap(draw2d.RoundCap)
|
||||||
gc.SetLineWidth(5)
|
gc.SetLineWidth(5)
|
||||||
gc.ArcTo(x+80, y+70, 50, 50, 180*(math.Pi/180), 360*(math.Pi/180)) // head
|
gc.ArcTo(x+80, y+70, 50, 50, 180*(math.Pi/180), 360*(math.Pi/180)) // head
|
||||||
|
|
|
@ -41,7 +41,7 @@ func initGc(w, h int) (image.Image, *draw2d.GraphicContext) {
|
||||||
|
|
||||||
func saveToPngFile(TestName string, m image.Image) {
|
func saveToPngFile(TestName string, m image.Image) {
|
||||||
dt := time.Nanoseconds() - lastTime
|
dt := time.Nanoseconds() - lastTime
|
||||||
fmt.Printf("%s during: %f ms\n", TestName, float(dt)*10e-6)
|
fmt.Printf("%s during: %f ms\n", TestName, float64(dt)*10e-6)
|
||||||
filePath := folder + TestName + ".png"
|
filePath := folder + TestName + ".png"
|
||||||
f, err := os.Open(filePath, os.O_CREAT|os.O_WRONLY, 0600)
|
f, err := os.Open(filePath, os.O_CREAT|os.O_WRONLY, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -79,12 +79,6 @@ func TestPath() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func cos(f float) float {
|
|
||||||
return float(math.Cos(float64(f)))
|
|
||||||
}
|
|
||||||
func sin(f float) float {
|
|
||||||
return float(math.Sin(float64(f)))
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
<img src="../test_results/TestDrawArc.png"/>
|
<img src="../test_results/TestDrawArc.png"/>
|
||||||
*/
|
*/
|
||||||
|
@ -106,7 +100,7 @@ func TestDrawArc() {
|
||||||
gc.SetLineWidth(6)
|
gc.SetLineWidth(6)
|
||||||
|
|
||||||
gc.MoveTo(xc, yc)
|
gc.MoveTo(xc, yc)
|
||||||
gc.LineTo(xc+cos(startAngle)*radiusX, yc+sin(startAngle)*radiusY)
|
gc.LineTo(xc+math.Cos(startAngle)*radiusX, yc+math.Sin(startAngle)*radiusY)
|
||||||
gc.MoveTo(xc, yc)
|
gc.MoveTo(xc, yc)
|
||||||
gc.LineTo(xc-radiusX, yc)
|
gc.LineTo(xc-radiusX, yc)
|
||||||
gc.Stroke()
|
gc.Stroke()
|
||||||
|
@ -137,7 +131,7 @@ func TestDrawArcNegative() {
|
||||||
gc.SetLineWidth(6)
|
gc.SetLineWidth(6)
|
||||||
|
|
||||||
gc.MoveTo(xc, yc)
|
gc.MoveTo(xc, yc)
|
||||||
gc.LineTo(xc+cos(startAngle)*radiusX, yc+sin(startAngle)*radiusY)
|
gc.LineTo(xc+math.Cos(startAngle)*radiusX, yc+math.Sin(startAngle)*radiusY)
|
||||||
gc.MoveTo(xc, yc)
|
gc.MoveTo(xc, yc)
|
||||||
gc.LineTo(xc-radiusX, yc)
|
gc.LineTo(xc-radiusX, yc)
|
||||||
gc.Stroke()
|
gc.Stroke()
|
||||||
|
@ -235,7 +229,7 @@ func TestDrawCubicCurve() {
|
||||||
*/
|
*/
|
||||||
func TestDash() {
|
func TestDash() {
|
||||||
i, gc := initGc(w, h)
|
i, gc := initGc(w, h)
|
||||||
gc.SetLineDash([]float{50, 10, 10, 10}, -50.0)
|
gc.SetLineDash([]float64{50, 10, 10, 10}, -50.0)
|
||||||
gc.SetLineCap(draw2d.ButtCap)
|
gc.SetLineCap(draw2d.ButtCap)
|
||||||
gc.SetLineJoin(draw2d.BevelJoin)
|
gc.SetLineJoin(draw2d.BevelJoin)
|
||||||
gc.SetLineWidth(10)
|
gc.SetLineWidth(10)
|
||||||
|
@ -487,8 +481,8 @@ func TestTransform() {
|
||||||
func TestPathTransform() {
|
func TestPathTransform() {
|
||||||
i, gc := initGc(800, 600)
|
i, gc := initGc(800, 600)
|
||||||
gc.SetLineWidth(20)
|
gc.SetLineWidth(20)
|
||||||
gc.Scale(1, 5)
|
gc.Scale(1, 4)
|
||||||
gc.ArcTo(200, 50, 50, 50, 0, math.Pi*2)
|
gc.ArcTo(200, 80, 50, 50, 0, math.Pi*2)
|
||||||
gc.Close()
|
gc.Close()
|
||||||
gc.Stroke()
|
gc.Stroke()
|
||||||
saveToPngFile("TestPathTransform", i)
|
saveToPngFile("TestPathTransform", i)
|
||||||
|
|
|
@ -39,7 +39,7 @@ func initGc(w, h int) (image.Image, *draw2d.GraphicContext) {
|
||||||
|
|
||||||
func saveToPngFile(TestName string, m image.Image) {
|
func saveToPngFile(TestName string, m image.Image) {
|
||||||
dt := time.Nanoseconds() - lastTime
|
dt := time.Nanoseconds() - lastTime
|
||||||
fmt.Printf("%s during: %f ms\n", TestName, float(dt)*10e-6)
|
fmt.Printf("%s during: %f ms\n", TestName, float64(dt)*10e-6)
|
||||||
filePath := folder + TestName + ".png"
|
filePath := folder + TestName + ".png"
|
||||||
f, err := os.Open(filePath, os.O_CREAT|os.O_WRONLY, 0600)
|
f, err := os.Open(filePath, os.O_CREAT|os.O_WRONLY, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -61,7 +61,7 @@ func saveToPngFile(TestName string, m image.Image) {
|
||||||
fmt.Printf("Wrote %s OK.\n", filePath)
|
fmt.Printf("Wrote %s OK.\n", filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func gordon(gc *draw2d.GraphicContext, x, y, w, h float) {
|
func gordon(gc *draw2d.GraphicContext, x, y, w, h float64) {
|
||||||
h23 := (h * 2) / 3
|
h23 := (h * 2) / 3
|
||||||
|
|
||||||
blf := image.RGBAColor{0, 0, 0, 0xff}
|
blf := image.RGBAColor{0, 0, 0, 0xff}
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
"image"
|
"image"
|
||||||
"time"
|
"time"
|
||||||
"image/png"
|
"image/png"
|
||||||
"draw2d"
|
//"draw2d"
|
||||||
//"draw2d.googlecode.com/svn/trunk/draw2d/src/pkg/draw2d"
|
"draw2d.googlecode.com/svn/trunk/draw2d/src/pkg/draw2d"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ func saveToPngFile(filePath string, m image.Image) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadFromPngFile(filePath string) image.Image {
|
func loadFromPngFile(filePath string) image.Image {
|
||||||
f, err := os.Open(filePath, 0, 0)
|
f, err := os.Open(filePath, 0, 0)
|
||||||
if f == nil {
|
if f == nil {
|
||||||
log.Printf("can't open file; err=%s\n", err.String())
|
log.Printf("can't open file; err=%s\n", err.String())
|
||||||
return nil
|
return nil
|
||||||
|
@ -53,7 +53,7 @@ func loadFromPngFile(filePath string) image.Image {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func testBubble(gc * draw2d.GraphicContext) {
|
func testBubble(gc *draw2d.GraphicContext) {
|
||||||
gc.BeginPath()
|
gc.BeginPath()
|
||||||
gc.MoveTo(75, 25)
|
gc.MoveTo(75, 25)
|
||||||
gc.QuadCurveTo(25, 25, 25, 62.5)
|
gc.QuadCurveTo(25, 25, 25, 62.5)
|
||||||
|
@ -67,16 +67,15 @@ func testBubble(gc * draw2d.GraphicContext) {
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
|
|
||||||
source := loadFromPngFile("../../Varna_Railway_Station_HDR.png")
|
source := loadFromPngFile("../../Varna_Railway_Station_HDR.png")
|
||||||
i := image.NewRGBA(1024, 768)
|
i := image.NewRGBA(1024, 768)
|
||||||
gc := draw2d.NewGraphicContext(i)
|
gc := draw2d.NewGraphicContext(i)
|
||||||
gc.Scale(2, 0.5)
|
gc.Scale(2, 0.5)
|
||||||
//gc.Translate(75, 25)
|
//gc.Translate(75, 25)
|
||||||
gc.Rotate(30 * math.Pi/180)
|
gc.Rotate(30 * math.Pi / 180)
|
||||||
lastTime := time.Nanoseconds()
|
lastTime := time.Nanoseconds()
|
||||||
gc.DrawImage(source)
|
gc.DrawImage(source)
|
||||||
dt := time.Nanoseconds() - lastTime
|
dt := time.Nanoseconds() - lastTime
|
||||||
fmt.Printf("Draw image: %f ms\n", float(dt)*1e-6)
|
fmt.Printf("Draw image: %f ms\n", float64(dt)*1e-6)
|
||||||
saveToPngFile("../../TestDrawImage.png", i)
|
saveToPngFile("../../TestDrawImage.png", i)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
//high level path creation
|
//high level path creation
|
||||||
|
|
||||||
|
|
||||||
func Rect(path Path, x1, y1, x2, y2 float) {
|
func Rect(path Path, x1, y1, x2, y2 float64) {
|
||||||
path.MoveTo(x1, y1)
|
path.MoveTo(x1, y1)
|
||||||
path.LineTo(x2, y1)
|
path.LineTo(x2, y1)
|
||||||
path.LineTo(x2, y2)
|
path.LineTo(x2, y2)
|
||||||
|
@ -18,7 +18,7 @@ func Rect(path Path, x1, y1, x2, y2 float) {
|
||||||
path.Close()
|
path.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func RoundRect(path Path, x1, y1, x2, y2, arcWidth, arcHeight float) {
|
func RoundRect(path Path, x1, y1, x2, y2, arcWidth, arcHeight float64) {
|
||||||
arcWidth = arcWidth / 2
|
arcWidth = arcWidth / 2
|
||||||
arcHeight = arcHeight / 2
|
arcHeight = arcHeight / 2
|
||||||
path.MoveTo(x1, y1+arcHeight)
|
path.MoveTo(x1, y1+arcHeight)
|
||||||
|
@ -32,12 +32,12 @@ func RoundRect(path Path, x1, y1, x2, y2, arcWidth, arcHeight float) {
|
||||||
path.Close()
|
path.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Ellipse(path Path, cx, cy, rx, ry float) {
|
func Ellipse(path Path, cx, cy, rx, ry float64) {
|
||||||
path.ArcTo(cx, cy, rx, ry, 0, -math.Pi*2)
|
path.ArcTo(cx, cy, rx, ry, 0, -math.Pi*2)
|
||||||
path.Close()
|
path.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Circle(path Path, cx, cy, radius float) {
|
func Circle(path Path, cx, cy, radius float64) {
|
||||||
path.ArcTo(cx, cy, radius, radius, 0, -math.Pi*2)
|
path.ArcTo(cx, cy, radius, radius, 0, -math.Pi*2)
|
||||||
path.Close()
|
path.Close()
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,30 +4,31 @@ package draw2d
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"freetype-go.googlecode.com/hg/freetype/raster"
|
"freetype-go.googlecode.com/hg/freetype/raster"
|
||||||
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
func arc(t VertexConverter, x, y, rx, ry, start, angle, scale float) (lastX, lastY float) {
|
func arc(t VertexConverter, x, y, rx, ry, start, angle, scale float64) (lastX, lastY float64) {
|
||||||
end := start + angle
|
end := start + angle
|
||||||
clockWise := true
|
clockWise := true
|
||||||
if angle < 0 {
|
if angle < 0 {
|
||||||
clockWise = false
|
clockWise = false
|
||||||
}
|
}
|
||||||
ra := (fabs(rx) + fabs(ry)) / 2
|
ra := (math.Fabs(rx) + math.Fabs(ry)) / 2
|
||||||
da := acos(ra/(ra+0.125/scale)) * 2
|
da := math.Acos(ra/(ra+0.125/scale)) * 2
|
||||||
//normalize
|
//normalize
|
||||||
if !clockWise {
|
if !clockWise {
|
||||||
da = -da
|
da = -da
|
||||||
}
|
}
|
||||||
angle = start + da
|
angle = start + da
|
||||||
var curX, curY float
|
var curX, curY float64
|
||||||
for {
|
for {
|
||||||
if (angle < end-da/4) != clockWise {
|
if (angle < end-da/4) != clockWise {
|
||||||
curX = x + cos(end)*rx
|
curX = x + math.Cos(end)*rx
|
||||||
curY = y + sin(end)*ry
|
curY = y + math.Sin(end)*ry
|
||||||
return curX, curY
|
return curX, curY
|
||||||
}
|
}
|
||||||
curX = x + cos(angle)*rx
|
curX = x + math.Cos(angle)*rx
|
||||||
curY = y + sin(angle)*ry
|
curY = y + math.Sin(angle)*ry
|
||||||
|
|
||||||
angle += da
|
angle += da
|
||||||
t.Vertex(curX, curY)
|
t.Vertex(curX, curY)
|
||||||
|
@ -36,28 +37,28 @@ func arc(t VertexConverter, x, y, rx, ry, start, angle, scale float) (lastX, las
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func arcAdder(adder raster.Adder, x, y, rx, ry, start, angle, scale float) raster.Point {
|
func arcAdder(adder raster.Adder, x, y, rx, ry, start, angle, scale float64) raster.Point {
|
||||||
end := start + angle
|
end := start + angle
|
||||||
clockWise := true
|
clockWise := true
|
||||||
if angle < 0 {
|
if angle < 0 {
|
||||||
clockWise = false
|
clockWise = false
|
||||||
}
|
}
|
||||||
ra := (fabs(rx) + fabs(ry)) / 2
|
ra := (math.Fabs(rx) + math.Fabs(ry)) / 2
|
||||||
da := acos(ra/(ra+0.125/scale)) * 2
|
da := math.Acos(ra/(ra+0.125/scale)) * 2
|
||||||
//normalize
|
//normalize
|
||||||
if !clockWise {
|
if !clockWise {
|
||||||
da = -da
|
da = -da
|
||||||
}
|
}
|
||||||
angle = start + da
|
angle = start + da
|
||||||
var curX, curY float
|
var curX, curY float64
|
||||||
for {
|
for {
|
||||||
if (angle < end-da/4) != clockWise {
|
if (angle < end-da/4) != clockWise {
|
||||||
curX = x + cos(end)*rx
|
curX = x + math.Cos(end)*rx
|
||||||
curY = y + sin(end)*ry
|
curY = y + math.Sin(end)*ry
|
||||||
return floatToPoint(curX, curY)
|
return floatToPoint(curX, curY)
|
||||||
}
|
}
|
||||||
curX = x + cos(angle)*rx
|
curX = x + math.Cos(angle)*rx
|
||||||
curY = y + sin(angle)*ry
|
curY = y + math.Sin(angle)*ry
|
||||||
|
|
||||||
angle += da
|
angle += da
|
||||||
adder.Add1(floatToPoint(curX, curY))
|
adder.Add1(floatToPoint(curX, curY))
|
||||||
|
|
|
@ -33,7 +33,7 @@ var (
|
||||||
The more this value is the less sharp turns will be cut.
|
The more this value is the less sharp turns will be cut.
|
||||||
Typically it should not exceed 10-15 degrees.
|
Typically it should not exceed 10-15 degrees.
|
||||||
*/
|
*/
|
||||||
func cubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4, approximationScale, angleTolerance, cuspLimit float) {
|
func cubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4, approximationScale, angleTolerance, cuspLimit float64) {
|
||||||
cuspLimit = computeCuspLimit(cuspLimit)
|
cuspLimit = computeCuspLimit(cuspLimit)
|
||||||
distanceToleranceSquare := 0.5 / approximationScale
|
distanceToleranceSquare := 0.5 / approximationScale
|
||||||
distanceToleranceSquare = distanceToleranceSquare * distanceToleranceSquare
|
distanceToleranceSquare = distanceToleranceSquare * distanceToleranceSquare
|
||||||
|
@ -44,7 +44,7 @@ func cubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4, approximatio
|
||||||
/*
|
/*
|
||||||
* see cubicBezier comments for approximationScale and angleTolerance definition
|
* see cubicBezier comments for approximationScale and angleTolerance definition
|
||||||
*/
|
*/
|
||||||
func quadraticBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, approximationScale, angleTolerance float) {
|
func quadraticBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, approximationScale, angleTolerance float64) {
|
||||||
distanceToleranceSquare := 0.5 / approximationScale
|
distanceToleranceSquare := 0.5 / approximationScale
|
||||||
distanceToleranceSquare = distanceToleranceSquare * distanceToleranceSquare
|
distanceToleranceSquare = distanceToleranceSquare * distanceToleranceSquare
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ func quadraticBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, approximationSca
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func computeCuspLimit(v float) (r float) {
|
func computeCuspLimit(v float64) (r float64) {
|
||||||
if v == 0.0 {
|
if v == 0.0 {
|
||||||
r = 0.0
|
r = 0.0
|
||||||
} else {
|
} else {
|
||||||
|
@ -65,7 +65,7 @@ func computeCuspLimit(v float) (r float) {
|
||||||
/**
|
/**
|
||||||
* http://www.antigrain.com/research/adaptive_bezier/index.html
|
* http://www.antigrain.com/research/adaptive_bezier/index.html
|
||||||
*/
|
*/
|
||||||
func recursiveQuadraticBezierBezier(v VertexConverter, x1, y1, x2, y2, x3, y3 float, level int, distanceToleranceSquare, angleTolerance float) {
|
func recursiveQuadraticBezierBezier(v VertexConverter, x1, y1, x2, y2, x3, y3 float64, level int, distanceToleranceSquare, angleTolerance float64) {
|
||||||
if level > CurveRecursionLimit {
|
if level > CurveRecursionLimit {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ func recursiveQuadraticBezierBezier(v VertexConverter, x1, y1, x2, y2, x3, y3 fl
|
||||||
|
|
||||||
dx := x3 - x1
|
dx := x3 - x1
|
||||||
dy := y3 - y1
|
dy := y3 - y1
|
||||||
d := fabs(((x2-x3)*dy - (y2-y3)*dx))
|
d := math.Fabs(((x2-x3)*dy - (y2-y3)*dx))
|
||||||
|
|
||||||
if d > CurveCollinearityEpsilon {
|
if d > CurveCollinearityEpsilon {
|
||||||
// Regular case
|
// Regular case
|
||||||
|
@ -97,7 +97,7 @@ func recursiveQuadraticBezierBezier(v VertexConverter, x1, y1, x2, y2, x3, y3 fl
|
||||||
|
|
||||||
// Angle & Cusp Condition
|
// Angle & Cusp Condition
|
||||||
//----------------------
|
//----------------------
|
||||||
da := fabs(atan2(y3-y2, x3-x2) - atan2(y2-y1, x2-x1))
|
da := math.Fabs(math.Atan2(y3-y2, x3-x2) - math.Atan2(y2-y1, x2-x1))
|
||||||
if da >= math.Pi {
|
if da >= math.Pi {
|
||||||
da = 2*math.Pi - da
|
da = 2*math.Pi - da
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ func recursiveQuadraticBezierBezier(v VertexConverter, x1, y1, x2, y2, x3, y3 fl
|
||||||
/**
|
/**
|
||||||
* http://www.antigrain.com/research/adaptive_bezier/index.html
|
* http://www.antigrain.com/research/adaptive_bezier/index.html
|
||||||
*/
|
*/
|
||||||
func recursiveCubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4 float, level int, distanceToleranceSquare, angleTolerance, cuspLimit float) {
|
func recursiveCubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4 float64, level int, distanceToleranceSquare, angleTolerance, cuspLimit float64) {
|
||||||
if level > CurveRecursionLimit {
|
if level > CurveRecursionLimit {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -170,8 +170,8 @@ func recursiveCubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4 floa
|
||||||
dx := x4 - x1
|
dx := x4 - x1
|
||||||
dy := y4 - y1
|
dy := y4 - y1
|
||||||
|
|
||||||
d2 := fabs(((x2-x4)*dy - (y2-y4)*dx))
|
d2 := math.Fabs(((x2-x4)*dy - (y2-y4)*dx))
|
||||||
d3 := fabs(((x3-x4)*dy - (y3-y4)*dx))
|
d3 := math.Fabs(((x3-x4)*dy - (y3-y4)*dx))
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case d2 <= CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
|
case d2 <= CurveCollinearityEpsilon && d3 <= CurveCollinearityEpsilon:
|
||||||
|
@ -234,7 +234,7 @@ func recursiveCubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4 floa
|
||||||
|
|
||||||
// Angle Condition
|
// Angle Condition
|
||||||
//----------------------
|
//----------------------
|
||||||
da1 := fabs(atan2(y4-y3, x4-x3) - atan2(y3-y2, x3-x2))
|
da1 := math.Fabs(math.Atan2(y4-y3, x4-x3) - math.Atan2(y3-y2, x3-x2))
|
||||||
if da1 >= math.Pi {
|
if da1 >= math.Pi {
|
||||||
da1 = 2*math.Pi - da1
|
da1 = 2*math.Pi - da1
|
||||||
}
|
}
|
||||||
|
@ -265,7 +265,7 @@ func recursiveCubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4 floa
|
||||||
|
|
||||||
// Angle Condition
|
// Angle Condition
|
||||||
//----------------------
|
//----------------------
|
||||||
da1 := fabs(atan2(y3-y2, x3-x2) - atan2(y2-y1, x2-x1))
|
da1 := math.Fabs(math.Atan2(y3-y2, x3-x2) - math.Atan2(y2-y1, x2-x1))
|
||||||
if da1 >= math.Pi {
|
if da1 >= math.Pi {
|
||||||
da1 = 2*math.Pi - da1
|
da1 = 2*math.Pi - da1
|
||||||
}
|
}
|
||||||
|
@ -299,9 +299,9 @@ func recursiveCubicBezier(v VertexConverter, x1, y1, x2, y2, x3, y3, x4, y4 floa
|
||||||
|
|
||||||
// Angle & Cusp Condition
|
// Angle & Cusp Condition
|
||||||
//----------------------
|
//----------------------
|
||||||
k := atan2(y3-y2, x3-x2)
|
k := math.Atan2(y3-y2, x3-x2)
|
||||||
da1 := fabs(k - atan2(y2-y1, x2-x1))
|
da1 := math.Fabs(k - math.Atan2(y2-y1, x2-x1))
|
||||||
da2 := fabs(atan2(y4-y3, x4-x3) - k)
|
da2 := math.Fabs(math.Atan2(y4-y3, x4-x3) - k)
|
||||||
if da1 >= math.Pi {
|
if da1 >= math.Pi {
|
||||||
da1 = 2*math.Pi - da1
|
da1 = 2*math.Pi - da1
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,13 @@ package draw2d
|
||||||
type DashVertexConverter struct {
|
type DashVertexConverter struct {
|
||||||
command VertexCommand
|
command VertexCommand
|
||||||
next VertexConverter
|
next VertexConverter
|
||||||
x, y, distance float
|
x, y, distance float64
|
||||||
dash []float
|
dash []float64
|
||||||
currentDash int
|
currentDash int
|
||||||
dashOffset float
|
dashOffset float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDashConverter(dash []float, dashOffset float, converter VertexConverter) *DashVertexConverter {
|
func NewDashConverter(dash []float64, dashOffset float64, converter VertexConverter) *DashVertexConverter {
|
||||||
var dasher DashVertexConverter
|
var dasher DashVertexConverter
|
||||||
dasher.dash = dash
|
dasher.dash = dash
|
||||||
dasher.currentDash = 0
|
dasher.currentDash = 0
|
||||||
|
@ -28,7 +28,7 @@ func (dasher *DashVertexConverter) NextCommand(cmd VertexCommand) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dasher *DashVertexConverter) Vertex(x, y float) {
|
func (dasher *DashVertexConverter) Vertex(x, y float64) {
|
||||||
switch dasher.command {
|
switch dasher.command {
|
||||||
case VertexStartCommand:
|
case VertexStartCommand:
|
||||||
dasher.start(x, y)
|
dasher.start(x, y)
|
||||||
|
@ -38,7 +38,7 @@ func (dasher *DashVertexConverter) Vertex(x, y float) {
|
||||||
dasher.command = VertexNoCommand
|
dasher.command = VertexNoCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dasher *DashVertexConverter) start(x, y float) {
|
func (dasher *DashVertexConverter) start(x, y float64) {
|
||||||
dasher.next.NextCommand(VertexStartCommand)
|
dasher.next.NextCommand(VertexStartCommand)
|
||||||
dasher.next.Vertex(x, y)
|
dasher.next.Vertex(x, y)
|
||||||
dasher.x, dasher.y = x, y
|
dasher.x, dasher.y = x, y
|
||||||
|
@ -46,7 +46,7 @@ func (dasher *DashVertexConverter) start(x, y float) {
|
||||||
dasher.currentDash = 0
|
dasher.currentDash = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dasher *DashVertexConverter) lineTo(x, y float) {
|
func (dasher *DashVertexConverter) lineTo(x, y float64) {
|
||||||
rest := dasher.dash[dasher.currentDash] - dasher.distance
|
rest := dasher.dash[dasher.currentDash] - dasher.distance
|
||||||
for rest < 0 {
|
for rest < 0 {
|
||||||
dasher.distance = dasher.distance - dasher.dash[dasher.currentDash]
|
dasher.distance = dasher.distance - dasher.dash[dasher.currentDash]
|
||||||
|
|
|
@ -16,7 +16,7 @@ func (dc *DemuxConverter) NextCommand(cmd VertexCommand) {
|
||||||
converter.NextCommand(cmd)
|
converter.NextCommand(cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (dc *DemuxConverter) Vertex(x, y float) {
|
func (dc *DemuxConverter) Vertex(x, y float64) {
|
||||||
for _, converter := range dc.converters {
|
for _, converter := range dc.converters {
|
||||||
converter.Vertex(x, y)
|
converter.Vertex(x, y)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,16 +31,16 @@ type GraphicContext struct {
|
||||||
type contextStack struct {
|
type contextStack struct {
|
||||||
tr MatrixTransform
|
tr MatrixTransform
|
||||||
path *PathStorage
|
path *PathStorage
|
||||||
lineWidth float
|
lineWidth float64
|
||||||
dash []float
|
dash []float64
|
||||||
dashOffset float
|
dashOffset float64
|
||||||
strokeColor image.Color
|
strokeColor image.Color
|
||||||
fillColor image.Color
|
fillColor image.Color
|
||||||
fillRule FillRule
|
fillRule FillRule
|
||||||
cap Cap
|
cap Cap
|
||||||
join Join
|
join Join
|
||||||
previous *contextStack
|
previous *contextStack
|
||||||
fontSize float
|
fontSize float64
|
||||||
fontData FontData
|
fontData FontData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,15 +89,15 @@ func (gc *GraphicContext) ComposeMatrixTransform(tr MatrixTransform) {
|
||||||
gc.current.tr = tr.Multiply(gc.current.tr)
|
gc.current.tr = tr.Multiply(gc.current.tr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) Rotate(angle float) {
|
func (gc *GraphicContext) Rotate(angle float64) {
|
||||||
gc.current.tr = NewRotationMatrix(angle).Multiply(gc.current.tr)
|
gc.current.tr = NewRotationMatrix(angle).Multiply(gc.current.tr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) Translate(tx, ty float) {
|
func (gc *GraphicContext) Translate(tx, ty float64) {
|
||||||
gc.current.tr = NewTranslationMatrix(tx, ty).Multiply(gc.current.tr)
|
gc.current.tr = NewTranslationMatrix(tx, ty).Multiply(gc.current.tr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) Scale(sx, sy float) {
|
func (gc *GraphicContext) Scale(sx, sy float64) {
|
||||||
gc.current.tr = NewScaleMatrix(sx, sy).Multiply(gc.current.tr)
|
gc.current.tr = NewScaleMatrix(sx, sy).Multiply(gc.current.tr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ func (gc *GraphicContext) SetFillRule(f FillRule) {
|
||||||
gc.current.fillRule = f
|
gc.current.fillRule = f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) SetLineWidth(lineWidth float) {
|
func (gc *GraphicContext) SetLineWidth(lineWidth float64) {
|
||||||
gc.current.lineWidth = lineWidth
|
gc.current.lineWidth = lineWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,16 +135,16 @@ func (gc *GraphicContext) SetLineJoin(join Join) {
|
||||||
gc.current.join = join
|
gc.current.join = join
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) SetLineDash(dash []float, dashOffset float) {
|
func (gc *GraphicContext) SetLineDash(dash []float64, dashOffset float64) {
|
||||||
gc.current.dash = dash
|
gc.current.dash = dash
|
||||||
gc.current.dashOffset = dashOffset
|
gc.current.dashOffset = dashOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) SetFontSize(fontSize float) {
|
func (gc *GraphicContext) SetFontSize(fontSize float64) {
|
||||||
gc.current.fontSize = fontSize
|
gc.current.fontSize = fontSize
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) GetFontSize() float {
|
func (gc *GraphicContext) GetFontSize() float64 {
|
||||||
return gc.current.fontSize
|
return gc.current.fontSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,24 +193,24 @@ func (gc *GraphicContext) Restore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) DrawImage(image image.Image) {
|
func (gc *GraphicContext) DrawImage(image image.Image) {
|
||||||
width := raster.Fix32(gc.PaintedImage.Bounds().Dx()* 256)
|
width := raster.Fix32(gc.PaintedImage.Bounds().Dx() * 256)
|
||||||
height := raster.Fix32(gc.PaintedImage.Bounds().Dy()* 256)
|
height := raster.Fix32(gc.PaintedImage.Bounds().Dy() * 256)
|
||||||
|
|
||||||
painter := raster.NewRGBAPainter(gc.PaintedImage)
|
painter := raster.NewRGBAPainter(gc.PaintedImage)
|
||||||
|
|
||||||
p0 := raster.Point{0,0}
|
p0 := raster.Point{0, 0}
|
||||||
p1 := raster.Point{0,0}
|
p1 := raster.Point{0, 0}
|
||||||
p2 := raster.Point{0,0}
|
p2 := raster.Point{0, 0}
|
||||||
p3 := raster.Point{0,0}
|
p3 := raster.Point{0, 0}
|
||||||
var i raster.Fix32 = 0
|
var i raster.Fix32 = 0
|
||||||
for ; i < width; i+=256 {
|
for ; i < width; i += 256 {
|
||||||
var j raster.Fix32 = 0
|
var j raster.Fix32 = 0
|
||||||
for ; j < height; j+=256 {
|
for ; j < height; j += 256 {
|
||||||
p0.X, p0.Y = i, j
|
p0.X, p0.Y = i, j
|
||||||
p1.X, p1.Y = p0.X + 256, p0.Y
|
p1.X, p1.Y = p0.X+256, p0.Y
|
||||||
p2.X, p2.Y = p1.X, p0.Y + 256
|
p2.X, p2.Y = p1.X, p0.Y+256
|
||||||
p3.X, p3.Y = p0.X, p2.Y
|
p3.X, p3.Y = p0.X, p2.Y
|
||||||
|
|
||||||
gc.current.tr.TransformRasterPoint(&p0, &p1, &p2, &p3)
|
gc.current.tr.TransformRasterPoint(&p0, &p1, &p2, &p3)
|
||||||
gc.fillRasterizer.Start(p0)
|
gc.fillRasterizer.Start(p0)
|
||||||
gc.fillRasterizer.Add1(p1)
|
gc.fillRasterizer.Add1(p1)
|
||||||
|
@ -228,51 +228,51 @@ func (gc *GraphicContext) BeginPath() {
|
||||||
gc.current.path = new(PathStorage)
|
gc.current.path = new(PathStorage)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) IsEmpty() bool{
|
func (gc *GraphicContext) IsEmpty() bool {
|
||||||
return gc.current.path.IsEmpty()
|
return gc.current.path.IsEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) LastPoint() (float, float){
|
func (gc *GraphicContext) LastPoint() (float64, float64) {
|
||||||
return gc.current.path.LastPoint()
|
return gc.current.path.LastPoint()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) MoveTo(x, y float) {
|
func (gc *GraphicContext) MoveTo(x, y float64) {
|
||||||
gc.current.path.MoveTo(x, y)
|
gc.current.path.MoveTo(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) RMoveTo(dx, dy float) {
|
func (gc *GraphicContext) RMoveTo(dx, dy float64) {
|
||||||
gc.current.path.RMoveTo(dx, dy)
|
gc.current.path.RMoveTo(dx, dy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) LineTo(x, y float) {
|
func (gc *GraphicContext) LineTo(x, y float64) {
|
||||||
gc.current.path.LineTo(x, y)
|
gc.current.path.LineTo(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) RLineTo(dx, dy float) {
|
func (gc *GraphicContext) RLineTo(dx, dy float64) {
|
||||||
gc.current.path.RLineTo(dx, dy)
|
gc.current.path.RLineTo(dx, dy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) QuadCurveTo(cx, cy, x, y float) {
|
func (gc *GraphicContext) QuadCurveTo(cx, cy, x, y float64) {
|
||||||
gc.current.path.QuadCurveTo(cx, cy, x, y)
|
gc.current.path.QuadCurveTo(cx, cy, x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) RQuadCurveTo(dcx, dcy, dx, dy float) {
|
func (gc *GraphicContext) RQuadCurveTo(dcx, dcy, dx, dy float64) {
|
||||||
gc.current.path.RQuadCurveTo(dcx, dcy, dx, dy)
|
gc.current.path.RQuadCurveTo(dcx, dcy, dx, dy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) CubicCurveTo(cx1, cy1, cx2, cy2, x, y float) {
|
func (gc *GraphicContext) CubicCurveTo(cx1, cy1, cx2, cy2, x, y float64) {
|
||||||
gc.current.path.CubicCurveTo(cx1, cy1, cx2, cy2, x, y)
|
gc.current.path.CubicCurveTo(cx1, cy1, cx2, cy2, x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy float) {
|
func (gc *GraphicContext) RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy float64) {
|
||||||
gc.current.path.RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy)
|
gc.current.path.RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) ArcTo(cx, cy, rx, ry, startAngle, angle float) {
|
func (gc *GraphicContext) ArcTo(cx, cy, rx, ry, startAngle, angle float64) {
|
||||||
gc.current.path.ArcTo(cx, cy, rx, ry, startAngle, angle)
|
gc.current.path.ArcTo(cx, cy, rx, ry, startAngle, angle)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) RArcTo(dcx, dcy, rx, ry, startAngle, angle float) {
|
func (gc *GraphicContext) RArcTo(dcx, dcy, rx, ry, startAngle, angle float64) {
|
||||||
gc.current.path.RArcTo(dcx, dcy, rx, ry, startAngle, angle)
|
gc.current.path.RArcTo(dcx, dcy, rx, ry, startAngle, angle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ func (gc *GraphicContext) Close() {
|
||||||
gc.current.path.Close()
|
gc.current.path.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gc *GraphicContext) FillString(text string) (cursor float) {
|
func (gc *GraphicContext) FillString(text string) (cursor float64) {
|
||||||
gc.freetype.SetSrc(image.NewColorImage(gc.current.strokeColor))
|
gc.freetype.SetSrc(image.NewColorImage(gc.current.strokeColor))
|
||||||
// Draw the text.
|
// Draw the text.
|
||||||
x, y := gc.current.path.LastPoint()
|
x, y := gc.current.path.LastPoint()
|
||||||
|
@ -302,7 +302,7 @@ func (gc *GraphicContext) FillString(text string) (cursor float) {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
x1, _ := gc.current.path.LastPoint()
|
x1, _ := gc.current.path.LastPoint()
|
||||||
x2, y2 := float(p.X)/256, float(p.Y)/256
|
x2, y2 := float64(p.X)/256, float64(p.Y)/256
|
||||||
gc.current.tr.InverseTransform(&x2, &y2)
|
gc.current.tr.InverseTransform(&x2, &y2)
|
||||||
width := x2 - x1
|
width := x2 - x1
|
||||||
return width
|
return width
|
||||||
|
@ -346,7 +346,7 @@ func (gc *GraphicContext) Stroke(paths ...*PathStorage) {
|
||||||
paths = append(paths, gc.current.path)
|
paths = append(paths, gc.current.path)
|
||||||
gc.strokeRasterizer.UseNonZeroWinding = true
|
gc.strokeRasterizer.UseNonZeroWinding = true
|
||||||
|
|
||||||
stroker := NewLineStroker(NewVertexMatrixTransform(gc.current.tr, NewVertexAdder(gc.strokeRasterizer)))
|
stroker := NewLineStroker(gc.current.cap, gc.current.join, NewVertexMatrixTransform(gc.current.tr, NewVertexAdder(gc.strokeRasterizer)))
|
||||||
stroker.HalfLineWidth = gc.current.lineWidth / 2
|
stroker.HalfLineWidth = gc.current.lineWidth / 2
|
||||||
var pathConverter *PathConverter
|
var pathConverter *PathConverter
|
||||||
if gc.current.dash != nil && len(gc.current.dash) > 0 {
|
if gc.current.dash != nil && len(gc.current.dash) > 0 {
|
||||||
|
@ -413,7 +413,7 @@ func (gc *GraphicContext) FillStroke(paths ...*PathStorage) {
|
||||||
|
|
||||||
filler := NewVertexMatrixTransform(gc.current.tr, NewVertexAdder(gc.fillRasterizer))
|
filler := NewVertexMatrixTransform(gc.current.tr, NewVertexAdder(gc.fillRasterizer))
|
||||||
|
|
||||||
stroker := NewLineStroker(NewVertexMatrixTransform(gc.current.tr, NewVertexAdder(gc.strokeRasterizer)))
|
stroker := NewLineStroker(gc.current.cap, gc.current.join, NewVertexMatrixTransform(gc.current.tr, NewVertexAdder(gc.strokeRasterizer)))
|
||||||
stroker.HalfLineWidth = gc.current.lineWidth / 2
|
stroker.HalfLineWidth = gc.current.lineWidth / 2
|
||||||
|
|
||||||
demux := NewDemuxConverter(filler, stroker)
|
demux := NewDemuxConverter(filler, stroker)
|
||||||
|
|
|
@ -7,41 +7,17 @@ import (
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
func fabs(x float) float {
|
func distance(x1, y1, x2, y2 float64) float64 {
|
||||||
switch {
|
|
||||||
case x < 0:
|
|
||||||
return -x
|
|
||||||
case x == 0:
|
|
||||||
return 0 // return correctly fabs(-0)
|
|
||||||
}
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
|
|
||||||
func cos(f float) float {
|
|
||||||
return float(math.Cos(float64(f)))
|
|
||||||
}
|
|
||||||
func sin(f float) float {
|
|
||||||
return float(math.Sin(float64(f)))
|
|
||||||
}
|
|
||||||
func acos(f float) float {
|
|
||||||
return float(math.Acos(float64(f)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func atan2(x, y float) float {
|
|
||||||
return float(math.Atan2(float64(x), float64(y)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func distance(x1, y1, x2, y2 float) float {
|
|
||||||
dx := x2 - x1
|
dx := x2 - x1
|
||||||
dy := y2 - y1
|
dy := y2 - y1
|
||||||
return float(math.Sqrt(float64(dx*dx + dy*dy)))
|
return float64(math.Sqrt(dx*dx + dy*dy))
|
||||||
}
|
}
|
||||||
|
|
||||||
func vectorDistance(dx, dy float) float {
|
func vectorDistance(dx, dy float64) float64 {
|
||||||
return float(math.Sqrt(float64(dx*dx + dy*dy)))
|
return float64(math.Sqrt(dx*dx + dy*dy))
|
||||||
}
|
}
|
||||||
|
|
||||||
func squareDistance(x1, y1, x2, y2 float) float {
|
func squareDistance(x1, y1, x2, y2 float64) float64 {
|
||||||
dx := x2 - x1
|
dx := x2 - x1
|
||||||
dy := y2 - y1
|
dy := y2 - y1
|
||||||
return dx*dx + dy*dy
|
return dx*dx + dy*dy
|
||||||
|
|
|
@ -4,16 +4,16 @@
|
||||||
package draw2d
|
package draw2d
|
||||||
|
|
||||||
type Path interface {
|
type Path interface {
|
||||||
MoveTo(x, y float)
|
MoveTo(x, y float64)
|
||||||
RMoveTo(dx, dy float)
|
RMoveTo(dx, dy float64)
|
||||||
LineTo(x, y float)
|
LineTo(x, y float64)
|
||||||
RLineTo(dx, dy float)
|
RLineTo(dx, dy float64)
|
||||||
QuadCurveTo(cx, cy, x, y float)
|
QuadCurveTo(cx, cy, x, y float64)
|
||||||
RQuadCurveTo(dcx, dcy, dx, dy float)
|
RQuadCurveTo(dcx, dcy, dx, dy float64)
|
||||||
CubicCurveTo(cx1, cy1, cx2, cy2, x, y float)
|
CubicCurveTo(cx1, cy1, cx2, cy2, x, y float64)
|
||||||
RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy float)
|
RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy float64)
|
||||||
ArcTo(cx, cy, rx, ry, startAngle, angle float)
|
ArcTo(cx, cy, rx, ry, startAngle, angle float64)
|
||||||
RArcTo(dcx, dcy, rx, ry, startAngle, angle float)
|
RArcTo(dcx, dcy, rx, ry, startAngle, angle float64)
|
||||||
Close()
|
Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,5 +30,5 @@ const (
|
||||||
|
|
||||||
type VertexConverter interface {
|
type VertexConverter interface {
|
||||||
NextCommand(cmd VertexCommand)
|
NextCommand(cmd VertexCommand)
|
||||||
Vertex(x, y float)
|
Vertex(x, y float64)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ type VertexAdder struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func floatToPoint(x, y float) raster.Point {
|
func floatToPoint(x, y float64) raster.Point {
|
||||||
return raster.Point{raster.Fix32(x * 256), raster.Fix32(y * 256)}
|
return raster.Point{raster.Fix32(x * 256), raster.Fix32(y * 256)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ func (vertexAdder *VertexAdder) NextCommand(cmd VertexCommand) {
|
||||||
vertexAdder.command = cmd
|
vertexAdder.command = cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vertexAdder *VertexAdder) Vertex(x, y float) {
|
func (vertexAdder *VertexAdder) Vertex(x, y float64) {
|
||||||
switch vertexAdder.command {
|
switch vertexAdder.command {
|
||||||
case VertexStartCommand:
|
case VertexStartCommand:
|
||||||
vertexAdder.adder.Start(floatToPoint(x, y))
|
vertexAdder.adder.Start(floatToPoint(x, y))
|
||||||
|
@ -42,7 +42,7 @@ func (vertexAdder *VertexAdder) Vertex(x, y float) {
|
||||||
type PathAdder struct {
|
type PathAdder struct {
|
||||||
adder raster.Adder
|
adder raster.Adder
|
||||||
lastPoint raster.Point
|
lastPoint raster.Point
|
||||||
ApproximationScale float
|
ApproximationScale float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPathAdder(adder raster.Adder) *PathAdder {
|
func NewPathAdder(adder raster.Adder) *PathAdder {
|
||||||
|
@ -60,7 +60,7 @@ func (pathAdder *PathAdder) Convert(paths ...*PathStorage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (pathAdder *PathAdder) ConvertCommand(cmd PathCmd, vertices ...float) int {
|
func (pathAdder *PathAdder) ConvertCommand(cmd PathCmd, vertices ...float64) int {
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case MoveTo:
|
case MoveTo:
|
||||||
pathAdder.lastPoint = floatToPoint(vertices[0], vertices[1])
|
pathAdder.lastPoint = floatToPoint(vertices[0], vertices[1])
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
|
|
||||||
type PathConverter struct {
|
type PathConverter struct {
|
||||||
converter VertexConverter
|
converter VertexConverter
|
||||||
ApproximationScale, AngleTolerance, CuspLimit float
|
ApproximationScale, AngleTolerance, CuspLimit float64
|
||||||
startX, startY, x, y float
|
startX, startY, x, y float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPathConverter(converter VertexConverter) *PathConverter {
|
func NewPathConverter(converter VertexConverter) *PathConverter {
|
||||||
|
@ -27,7 +27,7 @@ func (c *PathConverter) Convert(paths ...*PathStorage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (c *PathConverter) ConvertCommand(cmd PathCmd, vertices ...float) int {
|
func (c *PathConverter) ConvertCommand(cmd PathCmd, vertices ...float64) int {
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case MoveTo:
|
case MoveTo:
|
||||||
c.MoveTo(vertices[0], vertices[1])
|
c.MoveTo(vertices[0], vertices[1])
|
||||||
|
@ -55,7 +55,7 @@ func (c *PathConverter) ConvertCommand(cmd PathCmd, vertices ...float) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PathConverter) MoveTo(x, y float) *PathConverter {
|
func (c *PathConverter) MoveTo(x, y float64) *PathConverter {
|
||||||
c.x, c.y = x, y
|
c.x, c.y = x, y
|
||||||
c.startX, c.startY = c.x, c.y
|
c.startX, c.startY = c.x, c.y
|
||||||
c.converter.NextCommand(VertexStopCommand)
|
c.converter.NextCommand(VertexStopCommand)
|
||||||
|
@ -64,12 +64,12 @@ func (c *PathConverter) MoveTo(x, y float) *PathConverter {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PathConverter) RMoveTo(dx, dy float) *PathConverter {
|
func (c *PathConverter) RMoveTo(dx, dy float64) *PathConverter {
|
||||||
c.MoveTo(c.x+dx, c.y+dy)
|
c.MoveTo(c.x+dx, c.y+dy)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PathConverter) LineTo(x, y float) *PathConverter {
|
func (c *PathConverter) LineTo(x, y float64) *PathConverter {
|
||||||
c.x, c.y = x, y
|
c.x, c.y = x, y
|
||||||
if c.startX == c.x && c.startY == c.y {
|
if c.startX == c.x && c.startY == c.y {
|
||||||
c.converter.NextCommand(VertexCloseCommand)
|
c.converter.NextCommand(VertexCloseCommand)
|
||||||
|
@ -79,12 +79,12 @@ func (c *PathConverter) LineTo(x, y float) *PathConverter {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PathConverter) RLineTo(dx, dy float) *PathConverter {
|
func (c *PathConverter) RLineTo(dx, dy float64) *PathConverter {
|
||||||
c.LineTo(c.x+dx, c.y+dy)
|
c.LineTo(c.x+dx, c.y+dy)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PathConverter) QuadCurveTo(cx, cy, x, y float) *PathConverter {
|
func (c *PathConverter) QuadCurveTo(cx, cy, x, y float64) *PathConverter {
|
||||||
quadraticBezier(c.converter, c.x, c.y, cx, cy, x, y, c.ApproximationScale, c.AngleTolerance)
|
quadraticBezier(c.converter, c.x, c.y, cx, cy, x, y, c.ApproximationScale, c.AngleTolerance)
|
||||||
c.x, c.y = x, y
|
c.x, c.y = x, y
|
||||||
if c.startX == c.x && c.startY == c.y {
|
if c.startX == c.x && c.startY == c.y {
|
||||||
|
@ -94,12 +94,12 @@ func (c *PathConverter) QuadCurveTo(cx, cy, x, y float) *PathConverter {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PathConverter) RQuadCurveTo(dcx, dcy, dx, dy float) *PathConverter {
|
func (c *PathConverter) RQuadCurveTo(dcx, dcy, dx, dy float64) *PathConverter {
|
||||||
c.QuadCurveTo(c.x+dcx, c.y+dcy, c.x+dx, c.y+dy)
|
c.QuadCurveTo(c.x+dcx, c.y+dcy, c.x+dx, c.y+dy)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PathConverter) CubicCurveTo(cx1, cy1, cx2, cy2, x, y float) *PathConverter {
|
func (c *PathConverter) CubicCurveTo(cx1, cy1, cx2, cy2, x, y float64) *PathConverter {
|
||||||
cubicBezier(c.converter, c.x, c.y, cx1, cy1, cx2, cy2, x, y, c.ApproximationScale, c.AngleTolerance, c.CuspLimit)
|
cubicBezier(c.converter, c.x, c.y, cx1, cy1, cx2, cy2, x, y, c.ApproximationScale, c.AngleTolerance, c.CuspLimit)
|
||||||
c.x, c.y = x, y
|
c.x, c.y = x, y
|
||||||
if c.startX == c.x && c.startY == c.y {
|
if c.startX == c.x && c.startY == c.y {
|
||||||
|
@ -109,12 +109,12 @@ func (c *PathConverter) CubicCurveTo(cx1, cy1, cx2, cy2, x, y float) *PathConver
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PathConverter) RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy float) *PathConverter {
|
func (c *PathConverter) RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy float64) *PathConverter {
|
||||||
c.CubicCurveTo(c.x+dcx1, c.y+dcy1, c.x+dcx2, c.y+dcy2, c.x+dx, c.y+dy)
|
c.CubicCurveTo(c.x+dcx1, c.y+dcy1, c.x+dcx2, c.y+dcy2, c.x+dx, c.y+dy)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PathConverter) ArcTo(cx, cy, rx, ry, startAngle, angle float) *PathConverter {
|
func (c *PathConverter) ArcTo(cx, cy, rx, ry, startAngle, angle float64) *PathConverter {
|
||||||
endAngle := startAngle + angle
|
endAngle := startAngle + angle
|
||||||
clockWise := true
|
clockWise := true
|
||||||
if angle < 0 {
|
if angle < 0 {
|
||||||
|
@ -130,8 +130,8 @@ func (c *PathConverter) ArcTo(cx, cy, rx, ry, startAngle, angle float) *PathConv
|
||||||
startAngle += math.Pi * 2.0
|
startAngle += math.Pi * 2.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
startX := cx + cos(startAngle)*rx
|
startX := cx + math.Cos(startAngle)*rx
|
||||||
startY := cy + sin(startAngle)*ry
|
startY := cy + math.Sin(startAngle)*ry
|
||||||
c.MoveTo(startX, startY)
|
c.MoveTo(startX, startY)
|
||||||
c.x, c.y = arc(c.converter, cx, cy, rx, ry, startAngle, angle, c.ApproximationScale)
|
c.x, c.y = arc(c.converter, cx, cy, rx, ry, startAngle, angle, c.ApproximationScale)
|
||||||
if c.startX == c.x && c.startY == c.y {
|
if c.startX == c.x && c.startY == c.y {
|
||||||
|
@ -141,7 +141,7 @@ func (c *PathConverter) ArcTo(cx, cy, rx, ry, startAngle, angle float) *PathConv
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PathConverter) RArcTo(dcx, dcy, rx, ry, startAngle, angle float) *PathConverter {
|
func (c *PathConverter) RArcTo(dcx, dcy, rx, ry, startAngle, angle float64) *PathConverter {
|
||||||
c.ArcTo(c.x+dcx, c.y+dcy, rx, ry, startAngle, angle)
|
c.ArcTo(c.x+dcx, c.y+dcy, rx, ry, startAngle, angle)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,11 @@ const (
|
||||||
|
|
||||||
type PathStorage struct {
|
type PathStorage struct {
|
||||||
commands []PathCmd
|
commands []PathCmd
|
||||||
vertices []float
|
vertices []float64
|
||||||
x, y float
|
x, y float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PathStorage) appendToPath(cmd PathCmd, vertices ...float) {
|
func (p *PathStorage) appendToPath(cmd PathCmd, vertices ...float64) {
|
||||||
p.commands = append(p.commands, cmd)
|
p.commands = append(p.commands, cmd)
|
||||||
p.vertices = append(p.vertices, vertices...)
|
p.vertices = append(p.vertices, vertices...)
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,11 @@ func (src *PathStorage) Copy() (dest *PathStorage) {
|
||||||
dest = new(PathStorage)
|
dest = new(PathStorage)
|
||||||
dest.commands = make([]PathCmd, len(src.commands))
|
dest.commands = make([]PathCmd, len(src.commands))
|
||||||
copy(dest.commands, src.commands)
|
copy(dest.commands, src.commands)
|
||||||
dest.vertices = make([]float, len(src.vertices))
|
dest.vertices = make([]float64, len(src.vertices))
|
||||||
copy(dest.vertices, src.vertices)
|
copy(dest.vertices, src.vertices)
|
||||||
return dest
|
return dest
|
||||||
}
|
}
|
||||||
func (p *PathStorage) LastPoint() (x, y float) {
|
func (p *PathStorage) LastPoint() (x, y float64) {
|
||||||
return p.x, p.y
|
return p.x, p.y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,59 +50,59 @@ func (p *PathStorage) Close() *PathStorage {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PathStorage) MoveTo(x, y float) *PathStorage {
|
func (p *PathStorage) MoveTo(x, y float64) *PathStorage {
|
||||||
p.appendToPath(MoveTo, x, y)
|
p.appendToPath(MoveTo, x, y)
|
||||||
p.x = x
|
p.x = x
|
||||||
p.y = y
|
p.y = y
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PathStorage) RMoveTo(dx, dy float) *PathStorage {
|
func (p *PathStorage) RMoveTo(dx, dy float64) *PathStorage {
|
||||||
x, y := p.LastPoint()
|
x, y := p.LastPoint()
|
||||||
p.MoveTo(x+dx, y+dy)
|
p.MoveTo(x+dx, y+dy)
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PathStorage) LineTo(x, y float) *PathStorage {
|
func (p *PathStorage) LineTo(x, y float64) *PathStorage {
|
||||||
p.appendToPath(LineTo, x, y)
|
p.appendToPath(LineTo, x, y)
|
||||||
p.x = x
|
p.x = x
|
||||||
p.y = y
|
p.y = y
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PathStorage) RLineTo(dx, dy float) *PathStorage {
|
func (p *PathStorage) RLineTo(dx, dy float64) *PathStorage {
|
||||||
x, y := p.LastPoint()
|
x, y := p.LastPoint()
|
||||||
p.LineTo(x+dx, y+dy)
|
p.LineTo(x+dx, y+dy)
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PathStorage) QuadCurveTo(cx, cy, x, y float) *PathStorage {
|
func (p *PathStorage) QuadCurveTo(cx, cy, x, y float64) *PathStorage {
|
||||||
p.appendToPath(QuadCurveTo, cx, cy, x, y)
|
p.appendToPath(QuadCurveTo, cx, cy, x, y)
|
||||||
p.x = x
|
p.x = x
|
||||||
p.y = y
|
p.y = y
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PathStorage) RQuadCurveTo(dcx, dcy, dx, dy float) *PathStorage {
|
func (p *PathStorage) RQuadCurveTo(dcx, dcy, dx, dy float64) *PathStorage {
|
||||||
x, y := p.LastPoint()
|
x, y := p.LastPoint()
|
||||||
p.RQuadCurveTo(x+dcx, y+dcy, x+dx, y+dy)
|
p.RQuadCurveTo(x+dcx, y+dcy, x+dx, y+dy)
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PathStorage) CubicCurveTo(cx1, cy1, cx2, cy2, x, y float) *PathStorage {
|
func (p *PathStorage) CubicCurveTo(cx1, cy1, cx2, cy2, x, y float64) *PathStorage {
|
||||||
p.appendToPath(CubicCurveTo, cx1, cy1, cx2, cy2, x, y)
|
p.appendToPath(CubicCurveTo, cx1, cy1, cx2, cy2, x, y)
|
||||||
p.x = x
|
p.x = x
|
||||||
p.y = y
|
p.y = y
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PathStorage) RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy float) *PathStorage {
|
func (p *PathStorage) RCubicCurveTo(dcx1, dcy1, dcx2, dcy2, dx, dy float64) *PathStorage {
|
||||||
x, y := p.LastPoint()
|
x, y := p.LastPoint()
|
||||||
p.RCubicCurveTo(x+dcx1, y+dcy1, x+dcx2, y+dcy2, x+dx, y+dy)
|
p.RCubicCurveTo(x+dcx1, y+dcy1, x+dcx2, y+dcy2, x+dx, y+dy)
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PathStorage) ArcTo(cx, cy, rx, ry, startAngle, angle float) *PathStorage {
|
func (p *PathStorage) ArcTo(cx, cy, rx, ry, startAngle, angle float64) *PathStorage {
|
||||||
endAngle := startAngle + angle
|
endAngle := startAngle + angle
|
||||||
clockWise := true
|
clockWise := true
|
||||||
if angle < 0 {
|
if angle < 0 {
|
||||||
|
@ -118,20 +118,20 @@ func (p *PathStorage) ArcTo(cx, cy, rx, ry, startAngle, angle float) *PathStorag
|
||||||
startAngle += math.Pi * 2.0
|
startAngle += math.Pi * 2.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
startX := cx + cos(startAngle)*rx
|
startX := cx + math.Cos(startAngle)*rx
|
||||||
startY := cy + sin(startAngle)*ry
|
startY := cy + math.Sin(startAngle)*ry
|
||||||
if len(p.commands) > 0 {
|
if len(p.commands) > 0 {
|
||||||
p.LineTo(startX, startY)
|
p.LineTo(startX, startY)
|
||||||
} else {
|
} else {
|
||||||
p.MoveTo(startX, startY)
|
p.MoveTo(startX, startY)
|
||||||
}
|
}
|
||||||
p.appendToPath(ArcTo, cx, cy, rx, ry, startAngle, angle)
|
p.appendToPath(ArcTo, cx, cy, rx, ry, startAngle, angle)
|
||||||
p.x = cx + cos(endAngle)*rx
|
p.x = cx + math.Cos(endAngle)*rx
|
||||||
p.y = cy + sin(endAngle)*ry
|
p.y = cy + math.Sin(endAngle)*ry
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PathStorage) RArcTo(dcx, dcy, rx, ry, startAngle, angle float) *PathStorage {
|
func (p *PathStorage) RArcTo(dcx, dcy, rx, ry, startAngle, angle float64) *PathStorage {
|
||||||
x, y := p.LastPoint()
|
x, y := p.LastPoint()
|
||||||
p.RArcTo(x+dcx, y+dcy, rx, ry, startAngle, angle)
|
p.RArcTo(x+dcx, y+dcy, rx, ry, startAngle, angle)
|
||||||
return p
|
return p
|
||||||
|
|
|
@ -22,23 +22,23 @@ const (
|
||||||
|
|
||||||
type LineStroker struct {
|
type LineStroker struct {
|
||||||
Next VertexConverter
|
Next VertexConverter
|
||||||
HalfLineWidth float
|
HalfLineWidth float64
|
||||||
Cap Cap
|
Cap Cap
|
||||||
Join Join
|
Join Join
|
||||||
vertices []float
|
vertices []float64
|
||||||
rewind []float
|
rewind []float64
|
||||||
x, y, nx, ny float
|
x, y, nx, ny float64
|
||||||
command VertexCommand
|
command VertexCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLineStroker(converter VertexConverter) *LineStroker {
|
func NewLineStroker(c Cap, j Join, converter VertexConverter) *LineStroker {
|
||||||
l := new(LineStroker)
|
l := new(LineStroker)
|
||||||
l.Next = converter
|
l.Next = converter
|
||||||
l.HalfLineWidth = 0.5
|
l.HalfLineWidth = 0.5
|
||||||
l.vertices = make([]float, 0)
|
l.vertices = make([]float64, 0)
|
||||||
l.rewind = make([]float, 0)
|
l.rewind = make([]float64, 0)
|
||||||
l.Cap = ButtCap
|
l.Cap = c
|
||||||
l.Join = MiterJoin
|
l.Join = j
|
||||||
l.command = VertexNoCommand
|
l.command = VertexNoCommand
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
@ -62,13 +62,13 @@ func (l *LineStroker) NextCommand(command VertexCommand) {
|
||||||
}
|
}
|
||||||
l.Next.NextCommand(VertexStopCommand)
|
l.Next.NextCommand(VertexStopCommand)
|
||||||
// reinit vertices
|
// reinit vertices
|
||||||
l.vertices = make([]float, 0)
|
l.vertices = make([]float64, 0)
|
||||||
l.rewind = make([]float, 0)
|
l.rewind = make([]float64, 0)
|
||||||
l.x, l.y, l.nx, l.ny = 0, 0, 0, 0
|
l.x, l.y, l.nx, l.ny = 0, 0, 0, 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LineStroker) Vertex(x, y float) {
|
func (l *LineStroker) Vertex(x, y float64) {
|
||||||
switch l.command {
|
switch l.command {
|
||||||
case VertexNoCommand:
|
case VertexNoCommand:
|
||||||
l.line(l.x, l.y, x, y)
|
l.line(l.x, l.y, x, y)
|
||||||
|
@ -92,7 +92,7 @@ func (l *LineStroker) closePolygon() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (l *LineStroker) line(x1, y1, x2, y2 float) {
|
func (l *LineStroker) line(x1, y1, x2, y2 float64) {
|
||||||
dx := (x2 - x1)
|
dx := (x2 - x1)
|
||||||
dy := (y2 - y1)
|
dy := (y2 - y1)
|
||||||
d := vectorDistance(dx, dy)
|
d := vectorDistance(dx, dy)
|
||||||
|
@ -105,7 +105,7 @@ func (l *LineStroker) line(x1, y1, x2, y2 float) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LineStroker) joinLine(x1, y1, nx1, ny1, x2, y2 float) {
|
func (l *LineStroker) joinLine(x1, y1, nx1, ny1, x2, y2 float64) {
|
||||||
dx := (x2 - x1)
|
dx := (x2 - x1)
|
||||||
dy := (y2 - y1)
|
dy := (y2 - y1)
|
||||||
d := vectorDistance(dx, dy)
|
d := vectorDistance(dx, dy)
|
||||||
|
|
|
@ -5,19 +5,20 @@ package draw2d
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"freetype-go.googlecode.com/hg/freetype/raster"
|
"freetype-go.googlecode.com/hg/freetype/raster"
|
||||||
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MatrixTransform [6]float
|
type MatrixTransform [6]float64
|
||||||
|
|
||||||
const (
|
const (
|
||||||
epsilon = 1e-6
|
epsilon = 1e-6
|
||||||
)
|
)
|
||||||
|
|
||||||
func (tr MatrixTransform) Determinant() float {
|
func (tr MatrixTransform) Determinant() float64 {
|
||||||
return tr[0]*tr[3] - tr[1]*tr[2]
|
return tr[0]*tr[3] - tr[1]*tr[2]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr MatrixTransform) Transform(points ...*float) {
|
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]
|
||||||
y := *points[j]
|
y := *points[j]
|
||||||
|
@ -28,14 +29,14 @@ func (tr MatrixTransform) Transform(points ...*float) {
|
||||||
|
|
||||||
func (tr MatrixTransform) TransformRasterPoint(points ...*raster.Point) {
|
func (tr MatrixTransform) TransformRasterPoint(points ...*raster.Point) {
|
||||||
for _, point := range points {
|
for _, point := range points {
|
||||||
x := float(point.X) / 256
|
x := float64(point.X) / 256
|
||||||
y := float(point.Y) / 256
|
y := float64(point.Y) / 256
|
||||||
point.X = raster.Fix32((x*tr[0] + y*tr[2] + tr[4]) * 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)
|
point.Y = raster.Fix32((x*tr[1] + y*tr[3] + tr[5]) * 256)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr MatrixTransform) InverseTransform(points ...*float) {
|
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 {
|
||||||
x := *points[i]
|
x := *points[i]
|
||||||
|
@ -47,7 +48,7 @@ func (tr MatrixTransform) InverseTransform(points ...*float) {
|
||||||
|
|
||||||
// ******************** Vector transformations ********************
|
// ******************** Vector transformations ********************
|
||||||
|
|
||||||
func (tr MatrixTransform) VectorTransform(points ...*float) {
|
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 {
|
||||||
x := *points[i]
|
x := *points[i]
|
||||||
y := *points[j]
|
y := *points[j]
|
||||||
|
@ -60,42 +61,42 @@ func (tr MatrixTransform) VectorTransform(points ...*float) {
|
||||||
|
|
||||||
/** Creates an identity transformation. */
|
/** Creates an identity transformation. */
|
||||||
func NewIdentityMatrix() MatrixTransform {
|
func NewIdentityMatrix() MatrixTransform {
|
||||||
return [6]float{1, 0, 0, 1, 0, 0}
|
return [6]float64{1, 0, 0, 1, 0, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a transformation with a translation, that,
|
* Creates a transformation with a translation, that,
|
||||||
* transform point1 into point2.
|
* transform point1 into point2.
|
||||||
*/
|
*/
|
||||||
func NewTranslationMatrix(tx, ty float) MatrixTransform {
|
func NewTranslationMatrix(tx, ty float64) MatrixTransform {
|
||||||
return [6]float{1, 0, 0, 1, tx, ty}
|
return [6]float64{1, 0, 0, 1, tx, ty}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a transformation with a sx, sy scale factor
|
* Creates a transformation with a sx, sy scale factor
|
||||||
*/
|
*/
|
||||||
func NewScaleMatrix(sx, sy float) MatrixTransform {
|
func NewScaleMatrix(sx, sy float64) MatrixTransform {
|
||||||
return [6]float{sx, 0, 0, sy, 0, 0}
|
return [6]float64{sx, 0, 0, sy, 0, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a rotation transformation.
|
* Creates a rotation transformation.
|
||||||
*/
|
*/
|
||||||
func NewRotationMatrix(angle float) MatrixTransform {
|
func NewRotationMatrix(angle float64) MatrixTransform {
|
||||||
c := cos(angle)
|
c := math.Cos(angle)
|
||||||
s := sin(angle)
|
s := math.Sin(angle)
|
||||||
return [6]float{c, s, -s, c, 0, 0}
|
return [6]float64{c, s, -s, c, 0, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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, rectangle2 [4]float) MatrixTransform {
|
func NewMatrixTransform(rectangle1, rectangle2 [4]float64) 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)
|
||||||
yOffset := rectangle2[1] - (rectangle1[1] * yScale)
|
yOffset := rectangle2[1] - (rectangle1[1] * yScale)
|
||||||
return [6]float{xScale, 0, 0, yScale, xOffset, yOffset}
|
return [6]float64{xScale, 0, 0, yScale, xOffset, yOffset}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ******************** Transformations operations ********************
|
// ******************** Transformations operations ********************
|
||||||
|
@ -105,7 +106,7 @@ func NewMatrixTransform(rectangle1, rectangle2 [4]float) MatrixTransform {
|
||||||
*/
|
*/
|
||||||
func (tr MatrixTransform) GetInverseTransformation() MatrixTransform {
|
func (tr MatrixTransform) GetInverseTransformation() MatrixTransform {
|
||||||
d := tr.Determinant() // matrix determinant
|
d := tr.Determinant() // matrix determinant
|
||||||
return [6]float{
|
return [6]float64{
|
||||||
tr[3] / d,
|
tr[3] / d,
|
||||||
-tr[1] / d,
|
-tr[1] / d,
|
||||||
-tr[2] / d,
|
-tr[2] / d,
|
||||||
|
@ -116,7 +117,7 @@ func (tr MatrixTransform) GetInverseTransformation() MatrixTransform {
|
||||||
|
|
||||||
|
|
||||||
func (tr1 MatrixTransform) Multiply(tr2 MatrixTransform) MatrixTransform {
|
func (tr1 MatrixTransform) Multiply(tr2 MatrixTransform) MatrixTransform {
|
||||||
return [6]float{
|
return [6]float64{
|
||||||
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],
|
||||||
tr1[2]*tr2[0] + tr1[3]*tr2[2],
|
tr1[2]*tr2[0] + tr1[3]*tr2[2],
|
||||||
|
@ -126,7 +127,7 @@ func (tr1 MatrixTransform) Multiply(tr2 MatrixTransform) MatrixTransform {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (tr *MatrixTransform) Scale(sx, sy float) *MatrixTransform {
|
func (tr *MatrixTransform) Scale(sx, sy float64) *MatrixTransform {
|
||||||
tr[0] = tr[0] * sx
|
tr[0] = tr[0] * sx
|
||||||
tr[1] = tr[1] * sx
|
tr[1] = tr[1] * sx
|
||||||
tr[4] = tr[4] * sx
|
tr[4] = tr[4] * sx
|
||||||
|
@ -136,15 +137,15 @@ func (tr *MatrixTransform) Scale(sx, sy float) *MatrixTransform {
|
||||||
return tr
|
return tr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr *MatrixTransform) Translate(tx, ty float) *MatrixTransform {
|
func (tr *MatrixTransform) Translate(tx, ty float64) *MatrixTransform {
|
||||||
tr[4] = tr[4] + tx
|
tr[4] = tr[4] + tx
|
||||||
tr[5] = tr[5] + ty
|
tr[5] = tr[5] + ty
|
||||||
return tr
|
return tr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr *MatrixTransform) Rotate(angle float) *MatrixTransform {
|
func (tr *MatrixTransform) Rotate(angle float64) *MatrixTransform {
|
||||||
ca := cos(angle)
|
ca := math.Cos(angle)
|
||||||
sa := sin(angle)
|
sa := math.Sin(angle)
|
||||||
t0 := tr[0]*ca - tr[1]*sa
|
t0 := tr[0]*ca - tr[1]*sa
|
||||||
t2 := tr[1]*ca - tr[3]*sa
|
t2 := tr[1]*ca - tr[3]*sa
|
||||||
t4 := tr[4]*ca - tr[5]*sa
|
t4 := tr[4]*ca - tr[5]*sa
|
||||||
|
@ -157,26 +158,26 @@ func (tr *MatrixTransform) Rotate(angle float) *MatrixTransform {
|
||||||
return tr
|
return tr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr MatrixTransform) GetTranslation() (x, y float) {
|
func (tr MatrixTransform) GetTranslation() (x, y float64) {
|
||||||
return tr[4], tr[5]
|
return tr[4], tr[5]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr MatrixTransform) GetScaling() (x, y float) {
|
func (tr MatrixTransform) GetScaling() (x, y float64) {
|
||||||
return tr[0], tr[3]
|
return tr[0], tr[3]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr MatrixTransform) GetMaxAbsScaling() (s float) {
|
func (tr MatrixTransform) GetMaxAbsScaling() (s float64) {
|
||||||
sx := fabs(tr[0])
|
sx := math.Fabs(tr[0])
|
||||||
sy := fabs(tr[3])
|
sy := math.Fabs(tr[3])
|
||||||
if sx > sy {
|
if sx > sy {
|
||||||
return sx
|
return sx
|
||||||
}
|
}
|
||||||
return sy
|
return sy
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tr MatrixTransform) GetMinAbsScaling() (s float) {
|
func (tr MatrixTransform) GetMinAbsScaling() (s float64) {
|
||||||
sx := fabs(tr[0])
|
sx := math.Fabs(tr[0])
|
||||||
sy := fabs(tr[3])
|
sy := math.Fabs(tr[3])
|
||||||
if sx > sy {
|
if sx > sy {
|
||||||
return sy
|
return sy
|
||||||
}
|
}
|
||||||
|
@ -218,8 +219,8 @@ func (tr MatrixTransform) IsTranslation() bool {
|
||||||
* Compares two floats.
|
* Compares two floats.
|
||||||
* return true if the distance between the two floats is less than epsilon, false otherwise
|
* return true if the distance between the two floats is less than epsilon, false otherwise
|
||||||
*/
|
*/
|
||||||
func fequals(float1, float2 float) bool {
|
func fequals(float1, float2 float64) bool {
|
||||||
return fabs(float1-float2) <= epsilon
|
return math.Fabs(float1-float2) <= epsilon
|
||||||
}
|
}
|
||||||
|
|
||||||
// this VertexConverter apply the Matrix transformation tr
|
// this VertexConverter apply the Matrix transformation tr
|
||||||
|
@ -237,7 +238,7 @@ func (vmt *VertexMatrixTransform) NextCommand(command VertexCommand) {
|
||||||
vmt.Next.NextCommand(command)
|
vmt.Next.NextCommand(command)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vmt *VertexMatrixTransform) Vertex(x, y float) {
|
func (vmt *VertexMatrixTransform) Vertex(x, y float64) {
|
||||||
vmt.tr.Transform(&x, &y)
|
vmt.tr.Transform(&x, &y)
|
||||||
vmt.Next.Vertex(x, y)
|
vmt.Next.Vertex(x, y)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue