2023-11-21 17:38:17 +00:00
|
|
|
package shapes
|
|
|
|
|
|
|
|
import (
|
|
|
|
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/math"
|
|
|
|
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/records"
|
|
|
|
"github.com/ctessum/geom"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ComplexPolygon struct {
|
|
|
|
Pol geom.Polygonal
|
|
|
|
}
|
|
|
|
|
2023-11-23 04:00:09 +00:00
|
|
|
func (p ComplexPolygon) Merge(o ComplexPolygon) ComplexPolygon {
|
|
|
|
return ComplexPolygon{
|
|
|
|
Pol: p.Pol.Union(o.Pol),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-21 17:38:17 +00:00
|
|
|
func (p ComplexPolygon) Intersect(o ComplexPolygon) ComplexPolygon {
|
|
|
|
return ComplexPolygon{
|
|
|
|
Pol: p.Pol.Intersection(o.Pol),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-23 04:00:09 +00:00
|
|
|
const PolygonSimplifyTolerance = 0.01
|
|
|
|
|
2023-11-21 17:38:17 +00:00
|
|
|
func (p ComplexPolygon) GetShape() (r *Shape) {
|
|
|
|
var edges []records.Record
|
|
|
|
for _, pol := range p.Pol.Polygons() {
|
2023-11-24 04:02:08 +00:00
|
|
|
for _, path := range pol.Simplify(0.01).(geom.Polygon) {
|
2023-11-23 04:00:09 +00:00
|
|
|
//pol = pol.Simplify(PolygonSimplifyTolerance).(geom.Polygon)
|
2023-11-21 17:38:17 +00:00
|
|
|
edges = append(edges, &records.LineRecord{
|
2023-11-22 10:08:09 +00:00
|
|
|
To: math.NewVector2(path[1].X, path[1].Y),
|
|
|
|
Start: math.NewVector2(path[0].X, path[0].Y),
|
2023-11-21 17:38:17 +00:00
|
|
|
})
|
|
|
|
for _, point := range path[2:] {
|
|
|
|
edges = append(edges, &records.LineRecord{
|
2023-11-22 10:08:09 +00:00
|
|
|
To: math.NewVector2(point.X, point.Y),
|
2023-11-21 17:38:17 +00:00
|
|
|
Start: edges[len(edges)-1].GetEnd(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return &Shape{
|
|
|
|
Edges: edges,
|
|
|
|
IsFlat: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPolygonFromShape(shape *Shape) (g geom.Polygon) {
|
|
|
|
flat := shape.Flatten()
|
|
|
|
|
|
|
|
var edges []*records.LineRecord
|
|
|
|
|
|
|
|
var lastEdge *records.LineRecord
|
|
|
|
|
|
|
|
for _, record := range flat.Edges {
|
|
|
|
if lastEdge != nil && !lastEdge.GetEnd().Equals(record.GetStart()) {
|
|
|
|
g = append(g, NewPathFromEdges(edges))
|
|
|
|
edges = edges[:0]
|
|
|
|
}
|
|
|
|
|
|
|
|
if lineRecord, ok := record.(*records.LineRecord); ok {
|
|
|
|
edges = append(edges, lineRecord)
|
|
|
|
lastEdge = lineRecord
|
|
|
|
} else {
|
|
|
|
panic("invalid record")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(edges) > 0 {
|
|
|
|
g = append(g, NewPathFromEdges(edges))
|
|
|
|
}
|
|
|
|
|
|
|
|
return g
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPathFromEdges(edges []*records.LineRecord) (p geom.Path) {
|
|
|
|
p = make(geom.Path, 0, len(edges)+1)
|
2023-11-22 10:08:09 +00:00
|
|
|
start := edges[0].Start
|
|
|
|
to := edges[0].To
|
2023-11-23 04:00:09 +00:00
|
|
|
|
2023-11-21 17:38:17 +00:00
|
|
|
p = append(p, geom.Point{
|
|
|
|
X: start.X,
|
|
|
|
Y: start.Y,
|
|
|
|
})
|
2023-11-23 04:00:09 +00:00
|
|
|
|
|
|
|
if !start.Equals(to) {
|
2023-11-21 17:38:17 +00:00
|
|
|
p = append(p, geom.Point{
|
|
|
|
X: to.X,
|
|
|
|
Y: to.Y,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-11-23 04:00:09 +00:00
|
|
|
for _, e := range edges[1:] {
|
2023-11-21 17:38:17 +00:00
|
|
|
p = append(p, geom.Point{
|
2023-11-23 04:00:09 +00:00
|
|
|
X: e.To.X,
|
|
|
|
Y: e.To.Y,
|
2023-11-21 17:38:17 +00:00
|
|
|
})
|
|
|
|
}
|
2023-11-23 04:00:09 +00:00
|
|
|
|
2023-11-21 17:38:17 +00:00
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p ComplexPolygon) Draw() []records.Record {
|
|
|
|
return p.GetShape().Edges
|
|
|
|
}
|