added ellipse function
This commit is contained in:
parent
950d2bb30a
commit
239ab21259
2 changed files with 78 additions and 3 deletions
68
path2d.go
68
path2d.go
|
@ -253,6 +253,71 @@ func (p *Path2D) BezierCurveTo(x1, y1, x2, y2, x3, y3 float64) {
|
||||||
p.LineTo(x3, y3)
|
p.LineTo(x3, y3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ellipse (see equivalent function on canvas type)
|
||||||
|
func (p *Path2D) Ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle float64, anticlockwise bool) {
|
||||||
|
checkSelfIntersection := len(p.p) > 0
|
||||||
|
|
||||||
|
rs, rc := math.Sincos(rotation)
|
||||||
|
|
||||||
|
lastWasMove := len(p.p) == 0 || p.p[len(p.p)-1].flags&pathMove != 0
|
||||||
|
|
||||||
|
if endAngle == startAngle {
|
||||||
|
s, c := math.Sincos(endAngle)
|
||||||
|
rx, ry := radiusX*c, radiusY*s
|
||||||
|
rx, ry = rx*rc-ry*rs, rx*rs+ry*rc
|
||||||
|
p.lineTo(x+rx, y+ry, checkSelfIntersection)
|
||||||
|
|
||||||
|
if lastWasMove {
|
||||||
|
p.p[len(p.p)-1].flags |= pathIsConvex
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!anticlockwise && endAngle < startAngle) || (anticlockwise && endAngle > startAngle) {
|
||||||
|
startAngle, endAngle = endAngle, startAngle
|
||||||
|
}
|
||||||
|
|
||||||
|
if !anticlockwise {
|
||||||
|
diff := endAngle - startAngle
|
||||||
|
if diff >= math.Pi*4 {
|
||||||
|
diff = math.Mod(diff, math.Pi*2) + math.Pi*2
|
||||||
|
endAngle = startAngle + diff
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
diff := startAngle - endAngle
|
||||||
|
if diff >= math.Pi*4 {
|
||||||
|
diff = math.Mod(diff, math.Pi*2)
|
||||||
|
endAngle = startAngle - diff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const step = math.Pi * 2 / 90
|
||||||
|
if !anticlockwise {
|
||||||
|
for a := startAngle; a < endAngle; a += step {
|
||||||
|
s, c := math.Sincos(a)
|
||||||
|
rx, ry := radiusX*c, radiusY*s
|
||||||
|
rx, ry = rx*rc-ry*rs, rx*rs+ry*rc
|
||||||
|
p.lineTo(x+rx, y+ry, checkSelfIntersection)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for a := startAngle; a > endAngle; a -= step {
|
||||||
|
s, c := math.Sincos(a)
|
||||||
|
rx, ry := radiusX*c, radiusY*s
|
||||||
|
rx, ry = rx*rc-ry*rs, rx*rs+ry*rc
|
||||||
|
p.lineTo(x+rx, y+ry, checkSelfIntersection)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s, c := math.Sincos(endAngle)
|
||||||
|
rx, ry := radiusX*c, radiusY*s
|
||||||
|
rx, ry = rx*rc-ry*rs, rx*rs+ry*rc
|
||||||
|
p.lineTo(x+rx, y+ry, checkSelfIntersection)
|
||||||
|
|
||||||
|
if lastWasMove {
|
||||||
|
p.p[len(p.p)-1].flags |= pathIsConvex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ClosePath (see equivalent function on canvas type)
|
// ClosePath (see equivalent function on canvas type)
|
||||||
func (p *Path2D) ClosePath() {
|
func (p *Path2D) ClosePath() {
|
||||||
if len(p.p) < 2 {
|
if len(p.p) < 2 {
|
||||||
|
@ -287,9 +352,6 @@ func (p *Path2D) Rect(x, y, w, h float64) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (p *Path2D) Ellipse(...) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
func runSubPaths(path []pathPoint, close bool, fn func(subPath []pathPoint) bool) {
|
func runSubPaths(path []pathPoint, close bool, fn func(subPath []pathPoint) bool) {
|
||||||
start := 0
|
start := 0
|
||||||
for i, p := range path {
|
for i, p := range path {
|
||||||
|
|
13
paths.go
13
paths.go
|
@ -57,6 +57,19 @@ func (cv *Canvas) QuadraticCurveTo(x1, y1, x2, y2 float64) {
|
||||||
cv.path.QuadraticCurveTo(tf1[0], tf1[1], tf2[0], tf2[1])
|
cv.path.QuadraticCurveTo(tf1[0], tf1[1], tf2[0], tf2[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ellipse adds an ellipse segment to the end of the path. x/y is the center,
|
||||||
|
// radiusX is the major axis radius, radiusY is the minor axis radius,
|
||||||
|
// rotation is the rotation of the ellipse in radians, startAngle and endAngle
|
||||||
|
// are angles in radians, and anticlockwise means that the line is added
|
||||||
|
// anticlockwise
|
||||||
|
func (cv *Canvas) Ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle float64, anticlockwise bool) {
|
||||||
|
tf := cv.tf(vec{x, y})
|
||||||
|
ax, ay := math.Sincos(startAngle)
|
||||||
|
startAngle2 := vec{ay, ax}.mulMat2(cv.state.transform.mat2()).atan2()
|
||||||
|
endAngle2 := startAngle2 + (endAngle - startAngle)
|
||||||
|
cv.path.Ellipse(tf[0], tf[1], radiusX, radiusY, rotation, startAngle2, endAngle2, anticlockwise)
|
||||||
|
}
|
||||||
|
|
||||||
// BezierCurveTo adds a bezier curve to the path. It uses the current end point
|
// BezierCurveTo adds a bezier curve to the path. It uses the current end point
|
||||||
// of the path, x1/y1 and x2/y2 define the curve, and x3/y3 is the end point
|
// of the path, x1/y1 and x2/y2 define the curve, and x3/y3 is the end point
|
||||||
func (cv *Canvas) BezierCurveTo(x1, y1, x2, y2, x3, y3 float64) {
|
func (cv *Canvas) BezierCurveTo(x1, y1, x2, y2, x3, y3 float64) {
|
||||||
|
|
Loading…
Reference in a new issue