func TraceArc(t Liner, x, y, rx, ry, start, angle, scale float64) (lastX, lastY float64) {
	end := start + angle
	clockWise := true
	if angle < 0 {
		clockWise = false
	}
	ra := (math.Abs(rx) + math.Abs(ry)) / 2
	da := math.Acos(ra/(ra+0.125/scale)) * 2
	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)
	}
}
TraceArc trace an arc using a Liner
package draw2dbase
import (
	"errors"
	"math"
)
const (
	CurveRecursionLimit = 32
)
func SubdivideCubic(c, c1, c2 []float64) {
	c1[0], c1[1] = c[0], c[1]
	c2[6], c2[7] = c[6], c[7]
	c1[2] = (c[0] + c[2]) / 2
	c1[3] = (c[1] + c[3]) / 2
	midX := (c[2] + c[4]) / 2
	midY := (c[3] + c[5]) / 2
	c2[4] = (c[4] + c[6]) / 2
	c2[5] = (c[5] + c[7]) / 2
	c1[4] = (c1[2] + midX) / 2
	c1[5] = (c1[3] + midY) / 2
	c2[2] = (midX + c2[4]) / 2
	c2[3] = (midY + c2[5]) / 2
	c1[6] = (c1[4] + c2[2]) / 2
	c1[7] = (c1[5] + c2[3]) / 2
	c2[0], c2[1] = c1[6], c1[7]
}
func TraceCubic(t Liner, cubic []float64, flatteningThreshold float64) error {
	if len(cubic) < 8 {
		return errors.New("cubic length must be >= 8")
	}
	var curves [CurveRecursionLimit * 8]float64
	copy(curves[0:8], cubic[0:8])
	i := 0
	var c []float64
	var dx, dy, d2, d3 float64
	for i >= 0 {
		c = curves[i:]
		dx = c[6] - c[0]
		dy = c[7] - c[1]
		d2 = math.Abs((c[2]-c[6])*dy - (c[3]-c[7])*dx)
		d3 = math.Abs((c[4]-c[6])*dy - (c[5]-c[7])*dx)
		if (d2+d3)*(d2+d3) <= flatteningThreshold*(dx*dx+dy*dy) || i == len(curves)-8 {
			t.LineTo(c[6], c[7])
			i -= 8
		} else {
			SubdivideCubic(c, curves[i+8:], curves[i:])
			i += 8
		}
	}
	return nil
}
func SubdivideQuad(c, c1, c2 []float64) {
	c1[0], c1[1] = c[0], c[1]
	c2[4], c2[5] = c[4], c[5]
	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
}
func TraceQuad(t Liner, quad []float64, flatteningThreshold float64) error {
	if len(quad) < 6 {
		return errors.New("quad length must be >= 6")
	}
	var curves [CurveRecursionLimit * 6]float64
	copy(curves[0:6], quad[0:6])
	i := 0
	var c []float64
	var dx, dy, d float64
	for i >= 0 {
		c = curves[i:]
		dx = c[4] - c[0]
		dy = c[5] - c[1]
		d = math.Abs(((c[2]-c[4])*dy - (c[3]-c[5])*dx))
		if (d*d) <= flatteningThreshold*(dx*dx+dy*dy) || i == len(curves)-6 {
			t.LineTo(c[4], c[5])
			i -= 6
		} else {
			SubdivideQuad(c, curves[i+6:], curves[i:])
			i += 6
		}
	}
	return nil
}