2015-04-16 09:51:13 +00:00
|
|
|
// Copyright 2010 The draw2d Authors. All rights reserved.
|
|
|
|
// created: 17/05/2011 by Laurent Le Goff
|
2015-04-22 17:07:03 +00:00
|
|
|
|
2012-01-13 09:14:12 +00:00
|
|
|
package curve
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math"
|
|
|
|
)
|
|
|
|
|
2015-04-23 08:05:48 +00:00
|
|
|
// x1, y1, cpx1, cpy2, x2, y2 float64
|
|
|
|
// type Quad [6]float64
|
2012-01-13 09:14:12 +00:00
|
|
|
|
2015-04-22 17:07:03 +00:00
|
|
|
// Subdivide a Bezier quad curve in 2 equivalents Bezier quad curves.
|
|
|
|
// c1 and c2 parameters are the resulting curves
|
2015-04-23 08:05:48 +00:00
|
|
|
func SubdivideQuad(c, c1, c2 []float64) {
|
2015-04-22 17:07:03 +00:00
|
|
|
// First point of c is the first point of c1
|
2012-01-13 09:14:12 +00:00
|
|
|
c1[0], c1[1] = c[0], c[1]
|
2015-04-22 17:07:03 +00:00
|
|
|
// Last point of c is the last point of c2
|
2012-01-13 09:14:12 +00:00
|
|
|
c2[4], c2[5] = c[4], c[5]
|
2015-04-22 17:07:03 +00:00
|
|
|
|
|
|
|
// Subdivide segment using midpoints
|
2012-01-13 09:14:12 +00:00
|
|
|
c1[2] = (c[0] + c[2]) / 2
|
|
|
|
c1[3] = (c[1] + c[3]) / 2
|
|
|
|
c2[2] = (c[2] + c[4]) / 2
|
|
|
|
c2[3] = (c[3] + c[5]) / 2
|
|
|
|
c1[4] = (c1[2] + c2[2]) / 2
|
|
|
|
c1[5] = (c1[3] + c2[3]) / 2
|
|
|
|
c2[0], c2[1] = c1[4], c1[5]
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-04-23 13:36:56 +00:00
|
|
|
// Trace generate lines subdividing the curve using a LineBuilder
|
2015-04-22 17:07:03 +00:00
|
|
|
// flattening_threshold helps determines the flattening expectation of the curve
|
2015-04-23 13:36:56 +00:00
|
|
|
func TraceQuad(t LineBuilder, quad []float64, flattening_threshold float64) {
|
2015-04-22 17:07:03 +00:00
|
|
|
// Allocates curves stack
|
2015-04-23 08:05:48 +00:00
|
|
|
var curves [CurveRecursionLimit * 6]float64
|
|
|
|
copy(curves[0:6], quad[0:6])
|
2012-01-13 09:14:12 +00:00
|
|
|
i := 0
|
2015-04-16 09:51:13 +00:00
|
|
|
// current curve
|
2015-04-23 08:05:48 +00:00
|
|
|
var c []float64
|
2012-01-13 09:14:12 +00:00
|
|
|
var dx, dy, d float64
|
|
|
|
|
|
|
|
for i >= 0 {
|
2015-04-23 08:05:48 +00:00
|
|
|
c = curves[i*6:]
|
2012-01-13 09:14:12 +00:00
|
|
|
dx = c[4] - c[0]
|
|
|
|
dy = c[5] - c[1]
|
|
|
|
|
|
|
|
d = math.Abs(((c[2]-c[4])*dy - (c[3]-c[5])*dx))
|
|
|
|
|
2015-04-22 17:07:03 +00:00
|
|
|
// if it's flat then trace a line
|
2012-01-13 09:14:12 +00:00
|
|
|
if (d*d) < flattening_threshold*(dx*dx+dy*dy) || i == len(curves)-1 {
|
2015-04-23 13:36:56 +00:00
|
|
|
t.LineTo(c[4], c[5])
|
2012-01-13 09:14:12 +00:00
|
|
|
i--
|
|
|
|
} else {
|
2015-04-16 09:51:13 +00:00
|
|
|
// second half of bezier go lower onto the stack
|
2015-04-23 08:05:48 +00:00
|
|
|
SubdivideQuad(c, curves[(i+1)*6:], curves[i*6:])
|
2012-01-13 09:14:12 +00:00
|
|
|
i++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|