-
Notifications
You must be signed in to change notification settings - Fork 0
/
pathsnipproc.go
88 lines (81 loc) · 2.15 KB
/
pathsnipproc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package graphics2d
import (
"github.com/jphsd/graphics2d/util"
)
// PathSnipProc contains the snip path.
type PathSnipProc struct {
Flatten float64
Path *Path
}
// NewPathSnipProc creates a new path snip path processor with the supplied path.
func NewPathSnipProc(path *Path) *PathSnipProc {
return &PathSnipProc{RenderFlatten, path}
}
// Process implements the PathProcessor interface.
func (psp *PathSnipProc) Process(p *Path) []*Path {
// Flatten the paths and get the parts
spparts := psp.Path.Flatten(psp.Flatten).Parts()
if len(spparts) == 0 {
return []*Path{p.Copy()}
}
pparts := p.Flatten(psp.Flatten).Parts()
if len(pparts) == 0 {
return []*Path{p.Copy()}
}
paths := [][][][]float64{pparts}
for _, sppart := range spparts {
npaths := [][][][]float64{}
for _, pparts := range paths {
npparts := [][][]float64{}
for _, ppart := range pparts {
splitparts := partsplit(sppart, ppart)
if splitparts == nil {
npparts = append(npparts, ppart)
continue
}
if splitparts[0] != nil {
npparts = append(npparts, splitparts[0])
}
if len(npparts) != 0 {
npaths = append(npaths, npparts)
}
if splitparts[1] != nil {
npparts = [][][]float64{splitparts[1]}
} else {
npparts = [][][]float64{}
}
}
if len(npparts) != 0 {
npaths = append(npaths, npparts)
}
}
paths = npaths
}
res := make([]*Path, len(paths))
for i, parts := range paths {
res[i] = PartsToPath(parts...)
}
return res
}
func partsplit(sppart, ppart [][]float64) [][][]float64 {
// TODO - is this faster than using PartsIntersection() which uses BB?
tvals, err := util.IntersectionTValsP(sppart[0], sppart[1], ppart[0], ppart[1])
if err != nil || tvals[0] < 0 || tvals[0] > 1 || tvals[1] < 0 || tvals[1] > 1 {
return nil
}
t := tvals[1]
if t > 0 && t < 1 {
// Split ppart into two
dx, dy := ppart[1][0]-ppart[0][0], ppart[1][1]-ppart[0][1]
dx *= t
dy *= t
ip := []float64{ppart[0][0] + dx, ppart[0][1] + dy}
return [][][]float64{{ppart[0], ip}, {ip, ppart[1]}}
}
if t < 1 {
// t is at start of part
return [][][]float64{nil, ppart}
}
// t is at end of part
return [][][]float64{ppart, nil}
}