106 lines
2.2 KiB
Go
106 lines
2.2 KiB
Go
package shapes
|
|
|
|
import (
|
|
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/math"
|
|
"github.com/ctessum/polyclip-go"
|
|
"slices"
|
|
)
|
|
|
|
type ClipPath struct {
|
|
Clip ComplexPolygon
|
|
}
|
|
|
|
func NewClipPath(shape Shape) *ClipPath {
|
|
return &ClipPath{
|
|
Clip: ComplexPolygon{
|
|
Pol: NewPolygonFromShape(shape),
|
|
},
|
|
}
|
|
}
|
|
|
|
func (c *ClipPath) AddShape(shape Shape) {
|
|
c.Clip = c.Clip.Merge(ComplexPolygon{Pol: NewPolygonFromShape(shape)})
|
|
}
|
|
|
|
func (c *ClipPath) GetShape() Shape {
|
|
return c.Clip.GetShape()
|
|
}
|
|
|
|
func (c *ClipPath) ApplyMatrixTransform(transform math.MatrixTransform, applyTranslation bool) *ClipPath {
|
|
pol := make(polyclip.Polygon, len(c.Clip.Pol))
|
|
for i, contour := range c.Clip.Pol {
|
|
pol[i] = make(polyclip.Contour, len(contour))
|
|
for j, p := range contour {
|
|
out := transform.ApplyToVector(math.NewVector2(p.X, p.Y), applyTranslation)
|
|
pol[i][j] = polyclip.Point{
|
|
X: out.X,
|
|
Y: out.Y,
|
|
}
|
|
}
|
|
}
|
|
return &ClipPath{
|
|
Clip: ComplexPolygon{
|
|
Pol: pol,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (c *ClipPath) Merge(o *ClipPath) *ClipPath {
|
|
return &ClipPath{
|
|
Clip: c.Clip.Merge(o.Clip),
|
|
}
|
|
}
|
|
|
|
// ClipShape Clips a shape, but attempts to recover original curved records
|
|
func (c *ClipPath) ClipShape(o Shape, recover bool) (r Shape) {
|
|
if !recover {
|
|
return c.Clip.Intersect(ComplexPolygon{
|
|
Pol: NewPolygonFromShape(o),
|
|
}).GetShape()
|
|
}
|
|
flatShape, correspondence := o.FlattenWithCorrespondence()
|
|
outShape := ComplexPolygon{
|
|
Pol: NewPolygonFromShape(flatShape),
|
|
}.Intersect(c.Clip).GetShape()
|
|
|
|
for i := 0; i < len(outShape); i++ {
|
|
var found bool
|
|
for j, e := range correspondence {
|
|
if func() bool {
|
|
k, l := i, 0
|
|
for {
|
|
if l >= len(e.Flattened) {
|
|
return true
|
|
}
|
|
if k >= len(outShape) {
|
|
return false
|
|
}
|
|
if !e.Flattened[l].Equals(outShape[k]) {
|
|
return false
|
|
}
|
|
k++
|
|
l++
|
|
}
|
|
}() {
|
|
//They are the same! Append entry back
|
|
i += len(e.Flattened) - 1
|
|
r = append(r, e.Original)
|
|
slices.Delete(correspondence, j, j+1)
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
r = append(r, outShape[i])
|
|
}
|
|
}
|
|
|
|
return r
|
|
}
|
|
|
|
func (c *ClipPath) Intersect(o *ClipPath) *ClipPath {
|
|
return &ClipPath{
|
|
Clip: c.Clip.Intersect(o.Clip),
|
|
}
|
|
}
|