Add arc segmentation
This commit is contained in:
parent
4dd2a24c2d
commit
f4a9d29b42
5 changed files with 49 additions and 12 deletions
37
draw2d/curve/arc.go
Normal file
37
draw2d/curve/arc.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2010 The draw2d Authors. All rights reserved.
|
||||
// created: 21/11/2010 by Laurent Le Goff
|
||||
package draw2d
|
||||
|
||||
import (
|
||||
"freetype-go.googlecode.com/hg/freetype/raster"
|
||||
"math"
|
||||
)
|
||||
|
||||
func SegmentArc(t LineTracer, x, y, rx, ry, start, angle, scale float64) {
|
||||
end := start + angle
|
||||
clockWise := true
|
||||
if angle < 0 {
|
||||
clockWise = false
|
||||
}
|
||||
ra := (math.Fabs(rx) + math.Fabs(ry)) / 2
|
||||
da := math.Acos(ra/(ra+0.125/scale)) * 2
|
||||
//normalize
|
||||
if !clockWise {
|
||||
da = -da
|
||||
}
|
||||
angle = start + da
|
||||
var curX, curY float64
|
||||
for {
|
||||
if (angle < end-da/4) != clockWise {
|
||||
curX = x + math.Cos(end)*rx
|
||||
curY = y + math.Sin(end)*ry
|
||||
return curX, curY
|
||||
}
|
||||
curX = x + math.Cos(angle)*rx
|
||||
curY = y + math.Sin(angle)*ry
|
||||
|
||||
angle += da
|
||||
t.LineTo(curX, curY)
|
||||
}
|
||||
t.LineTo(curX, curY)
|
||||
}
|
|
@ -40,9 +40,6 @@ func (c *CubicCurveFloat64) Subdivide(c1, c2 *CubicCurveFloat64) (x23, y23 float
|
|||
}
|
||||
|
||||
func (curve *CubicCurveFloat64) Segment(t LineTracer, flattening_threshold float64) {
|
||||
// Add the first point
|
||||
t.LineTo(curve.X1, curve.Y1)
|
||||
|
||||
var curves [CurveRecursionLimit]CubicCurveFloat64
|
||||
curves[0] = *curve
|
||||
i := 0
|
||||
|
|
|
@ -63,8 +63,6 @@ func (c *CubicCurveFloat64) EstimateDistance() float64 {
|
|||
|
||||
// subdivide the curve in straight lines using line approximation and Casteljau recursive subdivision
|
||||
func (c *CubicCurveFloat64) SegmentRec(t LineTracer, flattening_threshold float64) {
|
||||
// reinit segments
|
||||
t.LineTo(c.X1, c.Y1)
|
||||
c.segmentRec(t, flattening_threshold)
|
||||
t.LineTo(c.X4, c.Y4)
|
||||
}
|
||||
|
@ -115,7 +113,6 @@ func (c *CubicCurveFloat64) AdaptiveSegmentRec(t LineTracer, approximationScale,
|
|||
cuspLimit = computeCuspLimit(cuspLimit)
|
||||
distanceToleranceSquare := 0.5 / approximationScale
|
||||
distanceToleranceSquare = distanceToleranceSquare * distanceToleranceSquare
|
||||
t.LineTo(c.X1, c.Y1)
|
||||
c.adaptiveSegmentRec(t, 0, distanceToleranceSquare, angleTolerance, cuspLimit)
|
||||
t.LineTo(c.X4, c.Y4)
|
||||
}
|
||||
|
@ -314,8 +311,6 @@ func (c *CubicCurveFloat64) adaptiveSegmentRec(t LineTracer, level int, distance
|
|||
}
|
||||
|
||||
func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale, angleTolerance, cuspLimit float64) {
|
||||
// Add the first point
|
||||
t.LineTo(curve.X1, curve.Y1)
|
||||
cuspLimit = computeCuspLimit(cuspLimit)
|
||||
distanceToleranceSquare := 0.5 / approximationScale
|
||||
distanceToleranceSquare = distanceToleranceSquare * distanceToleranceSquare
|
||||
|
@ -529,7 +524,6 @@ func (curve *CubicCurveFloat64) AdaptiveSegment(t LineTracer, approximationScale
|
|||
|
||||
|
||||
func (c *CubicCurveFloat64) ParabolicSegment(t LineTracer, flattening_threshold float64) {
|
||||
t.LineTo(c.X1, c.Y1)
|
||||
estimatedIFP := c.numberOfInflectionPoints()
|
||||
if estimatedIFP == 0 {
|
||||
// If no inflection points then apply PA on the full Bezier segment.
|
||||
|
|
|
@ -108,6 +108,7 @@ func drawPoints(img draw.Image, c image.Color, s ...float64) image.Image {
|
|||
func TestCubicCurveRec(t *testing.T) {
|
||||
for i, curve := range testsCubicFloat64 {
|
||||
var p Path
|
||||
p.LineTo(curve.X1, Y1)
|
||||
curve.SegmentRec(&p, flattening_threshold)
|
||||
img := image.NewNRGBA(300, 300)
|
||||
raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve.X1, curve.Y1, curve.X2, curve.Y2, curve.X3, curve.Y3, curve.X4, curve.Y4)
|
||||
|
@ -123,6 +124,7 @@ func TestCubicCurveRec(t *testing.T) {
|
|||
func TestCubicCurve(t *testing.T) {
|
||||
for i, curve := range testsCubicFloat64 {
|
||||
var p Path
|
||||
p.LineTo(curve.X1, Y1)
|
||||
curve.Segment(&p, flattening_threshold)
|
||||
img := image.NewNRGBA(300, 300)
|
||||
raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve.X1, curve.Y1, curve.X2, curve.Y2, curve.X3, curve.Y3, curve.X4, curve.Y4)
|
||||
|
@ -138,6 +140,7 @@ func TestCubicCurve(t *testing.T) {
|
|||
func TestCubicCurveAdaptiveRec(t *testing.T) {
|
||||
for i, curve := range testsCubicFloat64 {
|
||||
var p Path
|
||||
p.LineTo(curve.X1, Y1)
|
||||
curve.AdaptiveSegmentRec(&p, 1, 0, 0)
|
||||
img := image.NewNRGBA(300, 300)
|
||||
raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve.X1, curve.Y1, curve.X2, curve.Y2, curve.X3, curve.Y3, curve.X4, curve.Y4)
|
||||
|
@ -153,6 +156,7 @@ func TestCubicCurveAdaptiveRec(t *testing.T) {
|
|||
func TestCubicCurveAdaptive(t *testing.T) {
|
||||
for i, curve := range testsCubicFloat64 {
|
||||
var p Path
|
||||
p.LineTo(curve.X1, Y1)
|
||||
curve.AdaptiveSegment(&p, 1, 0, 0)
|
||||
img := image.NewNRGBA(300, 300)
|
||||
raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve.X1, curve.Y1, curve.X2, curve.Y2, curve.X3, curve.Y3, curve.X4, curve.Y4)
|
||||
|
@ -168,6 +172,7 @@ func TestCubicCurveAdaptive(t *testing.T) {
|
|||
func TestCubicCurveParabolic(t *testing.T) {
|
||||
for i, curve := range testsCubicFloat64 {
|
||||
var p Path
|
||||
p.LineTo(curve.X1, Y1)
|
||||
curve.ParabolicSegment(&p, flattening_threshold)
|
||||
img := image.NewNRGBA(300, 300)
|
||||
raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve.X1, curve.Y1, curve.X2, curve.Y2, curve.X3, curve.Y3, curve.X4, curve.Y4)
|
||||
|
@ -184,6 +189,7 @@ func TestCubicCurveParabolic(t *testing.T) {
|
|||
func TestQuadCurve(t *testing.T) {
|
||||
for i, curve := range testsQuadFloat64 {
|
||||
var p Path
|
||||
p.LineTo(curve.X1, Y1)
|
||||
curve.Segment(&p, flattening_threshold)
|
||||
img := image.NewNRGBA(300, 300)
|
||||
raster.PolylineBresenham(img, image.NRGBAColor{0xff, 0, 0, 0xff}, curve.X1, curve.Y1, curve.X2, curve.Y2, curve.X3, curve.Y3)
|
||||
|
@ -199,6 +205,7 @@ func BenchmarkCubicCurveRec(b *testing.B) {
|
|||
for i := 0; i < b.N; i++ {
|
||||
for _, curve := range testsCubicFloat64 {
|
||||
p := Path{make([]float64, 0, 32)}
|
||||
p.LineTo(curve.X1, Y1)
|
||||
curve.SegmentRec(&p, flattening_threshold)
|
||||
}
|
||||
}
|
||||
|
@ -208,6 +215,7 @@ func BenchmarkCubicCurve(b *testing.B) {
|
|||
for i := 0; i < b.N; i++ {
|
||||
for _, curve := range testsCubicFloat64 {
|
||||
p := Path{make([]float64, 0, 32)}
|
||||
p.LineTo(curve.X1, Y1)
|
||||
curve.Segment(&p, flattening_threshold)
|
||||
}
|
||||
}
|
||||
|
@ -217,6 +225,7 @@ func BenchmarkCubicCurveAdaptiveRec(b *testing.B) {
|
|||
for i := 0; i < b.N; i++ {
|
||||
for _, curve := range testsCubicFloat64 {
|
||||
p := Path{make([]float64, 0, 32)}
|
||||
p.LineTo(curve.X1, Y1)
|
||||
curve.AdaptiveSegmentRec(&p, 1, 0, 0)
|
||||
}
|
||||
}
|
||||
|
@ -226,6 +235,7 @@ func BenchmarkCubicCurveAdaptive(b *testing.B) {
|
|||
for i := 0; i < b.N; i++ {
|
||||
for _, curve := range testsCubicFloat64 {
|
||||
p := Path{make([]float64, 0, 32)}
|
||||
p.LineTo(curve.X1, Y1)
|
||||
curve.AdaptiveSegment(&p, 1, 0, 0)
|
||||
}
|
||||
}
|
||||
|
@ -235,6 +245,7 @@ func BenchmarkCubicCurveParabolic(b *testing.B) {
|
|||
for i := 0; i < b.N; i++ {
|
||||
for _, curve := range testsCubicFloat64 {
|
||||
p := Path{make([]float64, 0, 32)}
|
||||
p.LineTo(curve.X1, Y1)
|
||||
curve.ParabolicSegment(&p, flattening_threshold)
|
||||
}
|
||||
}
|
||||
|
@ -244,6 +255,7 @@ func BenchmarkQuadCurve(b *testing.B) {
|
|||
for i := 0; i < b.N; i++ {
|
||||
for _, curve := range testsQuadFloat64 {
|
||||
p := Path{make([]float64, 0, 32)}
|
||||
p.LineTo(curve.X1, Y1)
|
||||
curve.Segment(&p, flattening_threshold)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,6 @@ func (c *QuadCurveFloat64) Subdivide(c1, c2 *QuadCurveFloat64) {
|
|||
|
||||
|
||||
func (curve *QuadCurveFloat64) Segment(t LineTracer, flattening_threshold float64) {
|
||||
// Add the first point
|
||||
t.LineTo(curve.X1, curve.Y1)
|
||||
|
||||
var curves [CurveRecursionLimit]QuadCurveFloat64
|
||||
curves[0] = *curve
|
||||
i := 0
|
||||
|
|
Loading…
Reference in a new issue