IsPointInStroke implemented

This commit is contained in:
Thomas Friedel 2019-04-17 11:31:53 +02:00
parent c9fcfbdd53
commit 857e6c4e47
3 changed files with 50 additions and 13 deletions

View file

@ -460,3 +460,9 @@ func (cv *Canvas) SetShadowBlur(r float64) {
func (cv *Canvas) IsPointInPath(x, y float64, rule pathRule) bool {
return cv.path.IsPointInPath(x, y, rule)
}
// IsPointInStroke returns true if the point is in the current
// path stroke
func (cv *Canvas) IsPointInStroke(x, y float64) bool {
return cv.path.IsPointInStroke(x, y)
}

View file

@ -5,6 +5,7 @@ import (
)
type Path2D struct {
cv *Canvas
p []pathPoint
move vec
cwSum float64
@ -28,8 +29,8 @@ const (
)
// NewPath2D creates a new Path2D and returns it
func NewPath2D() *Path2D {
return &Path2D{p: make([]pathPoint, 0, 20)}
func (cv *Canvas) NewPath2D() *Path2D {
return &Path2D{cv: cv, p: make([]pathPoint, 0, 20)}
}
// func (p *Path2D) AddPath(p2 *Path2D) {
@ -344,3 +345,25 @@ func (p *Path2D) IsPointInPath(x, y float64, rule pathRule) bool {
})
return inside
}
// IsPointInStroke returns true if the point is in the stroke
func (p *Path2D) IsPointInStroke(x, y float64) bool {
if len(p.p) == 0 {
return false
}
var triBuf [500][2]float64
tris := p.cv.strokeTris(p, mat{}, false, triBuf[:0])
pt := vec{x, y}
for i := 0; i < len(tris); i += 3 {
a := vec{tris[i][0], tris[i][1]}
b := vec{tris[i+1][0], tris[i+1][1]}
c := vec{tris[i+2][0], tris[i+2][1]}
if triangleContainsPoint(a, b, c, pt) {
return true
}
}
return false
}

View file

@ -92,6 +92,20 @@ func (cv *Canvas) strokePath(path *Path2D, inv mat, doInv bool) {
return
}
var triBuf [500][2]float64
tris := cv.strokeTris(path, inv, doInv, triBuf[:0])
cv.drawShadow2(tris, nil)
stl := cv.backendFillStyle(&cv.state.stroke, 1)
cv.b.Fill(&stl, tris)
}
func (cv *Canvas) strokeTris(path *Path2D, inv mat, doInv bool, target [][2]float64) [][2]float64 {
if len(path.p) == 0 {
return target
}
if doInv {
for i, pt := range path.p {
path.p[i].pos = pt.pos.mulMat(inv)
@ -101,9 +115,6 @@ func (cv *Canvas) strokePath(path *Path2D, inv mat, doInv bool) {
dashedPath := cv.applyLineDash(path.p)
var triBuf [500][2]float64
tris := triBuf[:0]
start := true
var p0 vec
for _, p := range dashedPath {
@ -131,7 +142,7 @@ func (cv *Canvas) strokePath(path *Path2D, inv mat, doInv bool) {
lp0 = lp0.sub(v0)
lp2 = lp2.sub(v0)
case Round:
tris = cv.addCircleTris(p0, cv.state.lineWidth*0.5, tris)
target = cv.addCircleTris(p0, cv.state.lineWidth*0.5, target)
}
}
@ -143,24 +154,21 @@ func (cv *Canvas) strokePath(path *Path2D, inv mat, doInv bool) {
lp1 = lp1.add(v0)
lp3 = lp3.add(v0)
case Round:
tris = cv.addCircleTris(p1, cv.state.lineWidth*0.5, tris)
target = cv.addCircleTris(p1, cv.state.lineWidth*0.5, target)
}
}
tris = append(tris, cv.tf(lp0), cv.tf(lp1), cv.tf(lp3), cv.tf(lp0), cv.tf(lp3), cv.tf(lp2))
target = append(target, cv.tf(lp0), cv.tf(lp1), cv.tf(lp3), cv.tf(lp0), cv.tf(lp3), cv.tf(lp2))
if p.flags&pathAttach != 0 && cv.state.lineWidth > 1 {
tris = cv.lineJoint(p0, p1, p.next, lp0, lp1, lp2, lp3, tris)
target = cv.lineJoint(p0, p1, p.next, lp0, lp1, lp2, lp3, target)
}
p0 = p1
start = false
}
cv.drawShadow2(tris, nil)
stl := cv.backendFillStyle(&cv.state.stroke, 1)
cv.b.Fill(&stl, tris)
return target
}
func (cv *Canvas) applyLineDash(path []pathPoint) []pathPoint {