|
@@ -1,14 +1,29 @@
|
|
package h2d.col;
|
|
package h2d.col;
|
|
import hxd.Math;
|
|
import hxd.Math;
|
|
|
|
|
|
|
|
+enum OffsetKind {
|
|
|
|
+ Square;
|
|
|
|
+ Miter;
|
|
|
|
+ Round( arc : Float );
|
|
|
|
+}
|
|
|
|
+
|
|
abstract IPolygon(Array<IPoint>) from Array<IPoint> to Array<IPoint> {
|
|
abstract IPolygon(Array<IPoint>) from Array<IPoint> to Array<IPoint> {
|
|
|
|
|
|
public var points(get, never) : Array<IPoint>;
|
|
public var points(get, never) : Array<IPoint>;
|
|
-
|
|
|
|
|
|
+ public var length(get, never) : Int;
|
|
|
|
+ inline function get_length() return this.length;
|
|
inline function get_points() return this;
|
|
inline function get_points() return this;
|
|
|
|
|
|
- public inline function new( points ) {
|
|
|
|
- this = points;
|
|
|
|
|
|
+ public inline function new( ?points ) {
|
|
|
|
+ this = points == null ? [] : points;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function addPoint( p : IPoint ) {
|
|
|
|
+ this.push(p);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function iterator() {
|
|
|
|
+ return new hxd.impl.ArrayIterator(this);
|
|
}
|
|
}
|
|
|
|
|
|
public function toPolygon( scale = 1. ) {
|
|
public function toPolygon( scale = 1. ) {
|
|
@@ -22,6 +37,45 @@ abstract IPolygon(Array<IPoint>) from Array<IPoint> to Array<IPoint> {
|
|
return b;
|
|
return b;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public function union( p : IPolygon, withHoles = false ) : IPolygons {
|
|
|
|
+ var c = new hxd.clipper.Clipper();
|
|
|
|
+ if( !withHoles ) c.resultKind = NoHoles;
|
|
|
|
+ c.addPolygon(this, Clip);
|
|
|
|
+ c.addPolygon(p,Clip);
|
|
|
|
+ return c.execute(Union, NonZero, NonZero);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function intersection( p : IPolygon, withHoles = false ) : IPolygons {
|
|
|
|
+ return clipperOp(p, Intersection, withHoles);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public inline function subtraction( p : IPolygon, withHoles = false ) : IPolygons {
|
|
|
|
+ return clipperOp(p, Difference, withHoles);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public function offset( delta : Float, kind : OffsetKind, withHoles = false ) : IPolygons {
|
|
|
|
+ var c = new hxd.clipper.Clipper.ClipperOffset();
|
|
|
|
+ switch( kind ) {
|
|
|
|
+ case Square:
|
|
|
|
+ c.addPolygon(this, Square, ClosedPol);
|
|
|
|
+ case Miter:
|
|
|
|
+ c.addPolygon(this, Miter, ClosedPol);
|
|
|
|
+ case Round(arc):
|
|
|
|
+ c.ArcTolerance = arc;
|
|
|
|
+ c.addPolygon(this, Round, ClosedPol);
|
|
|
|
+ }
|
|
|
|
+ if( !withHoles ) c.resultKind = NoHoles;
|
|
|
|
+ return c.execute(delta);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function clipperOp( p : IPolygon, op, withHoles ) : IPolygons {
|
|
|
|
+ var c = new hxd.clipper.Clipper();
|
|
|
|
+ if( !withHoles ) c.resultKind = NoHoles;
|
|
|
|
+ c.addPolygon(this, Subject);
|
|
|
|
+ c.addPolygon(p, Clip);
|
|
|
|
+ return c.execute(op, NonZero, NonZero);
|
|
|
|
+ }
|
|
|
|
+
|
|
public function convexHull() {
|
|
public function convexHull() {
|
|
inline function side(p1 : IPoint, p2 : IPoint, p3 : IPoint) {
|
|
inline function side(p1 : IPoint, p2 : IPoint, p3 : IPoint) {
|
|
return (p2.y - p1.y) * (p3.x - p2.x) - (p2.x - p1.x) * (p3.y - p2.y);
|
|
return (p2.y - p1.y) * (p3.x - p2.x) - (p2.x - p1.x) * (p3.y - p2.y);
|
|
@@ -95,7 +149,7 @@ abstract IPolygon(Array<IPoint>) from Array<IPoint> to Array<IPoint> {
|
|
this.reverse();
|
|
this.reverse();
|
|
}
|
|
}
|
|
|
|
|
|
- public inline function contains( p : Point, isConvex ) {
|
|
|
|
|
|
+ public function contains( p : Point, isConvex ) {
|
|
if( isConvex ) {
|
|
if( isConvex ) {
|
|
var p1 = points[points.length - 1];
|
|
var p1 = points[points.length - 1];
|
|
for( p2 in points ) {
|
|
for( p2 in points ) {
|