diff --git a/js-clipper/js-clipper-tests.ts b/js-clipper/js-clipper-tests.ts new file mode 100644 index 0000000000..316b3ab578 --- /dev/null +++ b/js-clipper/js-clipper-tests.ts @@ -0,0 +1,19 @@ +/// + +class jsClipperTest{ + public intPointTest(){ + + let v1: ClipperLib.IntPoint = new ClipperLib.IntPoint(10, 10); + console.log("def: v1 - " + v1.X.toString() + v1.Y.toString()); + let v2: ClipperLib.IntPoint = new ClipperLib.IntPoint(20, 20); + console.log("def: v2 - " + v2.X.toString() + v1.Y.toString()); + let v3: ClipperLib.IntPoint = new ClipperLib.IntPoint(30, 30); + console.log("def: v3 -" + v3.X.toString() + v1.Y.toString()); + console.log("perp: v3 - " + v3.X.toString() + v3.Y.toString()); + + } +} + +var tt = new jsClipperTest; + +tt.intPointTest(); diff --git a/js-clipper/js-clipper.d.ts b/js-clipper/js-clipper.d.ts new file mode 100644 index 0000000000..351815ab84 --- /dev/null +++ b/js-clipper/js-clipper.d.ts @@ -0,0 +1,302 @@ +// Type definitions for js-clipper +// Project: https://github.com/mathisonian/JsClipper +// Definitions by: Hou Chunlei +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// +declare module ClipperLib { + + export var biginteger_used: boolean; + export function Math_Abs_Int64(a: number): number; + export function Math_Abs_Int32(a: number): number; + export function Math_Abs_Double(a: number): number; + export function Math_Max_Int32_Int32(a: number, b: number): number; + export function Cast_Int32(a: number): number; + export function Cast_Int64(a: number): number; + export function Clear(a: ArrayLike): void; + + export var MaxSteps: number; + export var PI: number; + export var PI2: number; + + export class IntPoint { + X: number; + Y: number; + constructor(); + constructor(PointXY: IntPoint); + constructor(x: number, y: number); + } + + export class IntRect { + left: number; + top: number; + right: number; + bottom: number; + constructor(); + constructor(left: number, top: number, right: number, bottom: number); + } + + export class Polygon { + constructor(); + constructor(poly: ArrayLike); + } + + export class Polygons { + constructor(); + constructor(polys: ArrayLike>); + } + + + export class ExPolygon { + outer: ArrayLike; + holes: ArrayLike>; + } + + export enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor } + export enum PolyType { ptSubject, ptClip } + export enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative } + export enum JoinType { jtSquare, jtRound, jtMiter } + export enum EdgeSide { esLeft, esRight } + export enum Protects { ipNone, ipLeft, ipRight, ipBoth } + export enum Direction { dRightToLeft, dLeftToRight } + + export class TEdge { + xbot: number; + ybot: number; + xcurr: number; + ycurr: number; + xtop: number; + ytop: number; + dx: number; + deltaX: number; + deltaY: number; + tmpX: number; + polyType: PolyType; + side: EdgeSide; + windDelta: number; + windCnt: number; + windCnt2: number; + outIdx: number; + next: TEdge; + prev: TEdge; + nextInLML: TEdge; + nextInAEL: TEdge; + prevInAEL: TEdge; + nextInSEL: TEdge; + prevInSEL: TEdge; + + } + export class IntersectNode { + edge1: TEdge; + edge2: TEdge; + pt: TEdge; + next: TEdge; + } + export class LocalMinima { + Y: number; + leftBound: TEdge; + rightBound: TEdge; + next: TEdge; + } + export class Scanbeam { + Y: number; + next: TEdge; + } + export class OutRec { + idx: number; + isHole: boolean; + FirstLeft: TEdge; + AppendLink: OutRec; + pts: OutPt; + bottomPt: OutPt; + + } + export class OutPt { + idx: number; + pt: OutPt; + next: OutPt; + prev: OutPt; + } + export class JoinRec { + pt1a: IntPoint; + pt1b: IntPoint; + poly1Idx: number; + pt2a: IntPoint; + pt2b: IntPoint; + poly2Idx: number; + } + export class HorzJoinRec { + edge: TEdge; + savedIdx: number; + } + export class ClipperBase { + m_MinimaList: LocalMinima; + m_CurrentLM: LocalMinima; + m_edges: ArrayLike>; + m_UseFullRange: boolean; + horizontal: number; + loRange: number; + hiRange: number; + + PointsEqual(pt1: IntPoint, pt2: IntPoint): boolean; + PointIsVertex(pt: IntPoint, pp: JoinRec): boolean; + PointInPolygon(pt: IntPoint, pp: JoinRec, UseFulllongRange: boolean): boolean; + SlopesEqual(e1: TEdge, e2: TEdge, UseFullRange: boolean): boolean; + SlopesEqual(pt1: IntPoint, pt2: IntPoint, pt3: IntPoint, UseFullRange: boolean): boolean; + SlopesEqual(pt1: IntPoint, pt2: IntPoint, pt3: IntPoint, pt4: IntPoint, UseFullRange: boolean): boolean; + clear(): void; + DisposeLocalMinimaList(): void; + AddPolygons(ppg: ArrayLike>, polyType: PolyType): boolean | string; + AddPolygon(pg: ArrayLike, polyType: PolyType, multiple: boolean): boolean | string; + InitEdge(e: TEdge, eNext: TEdge, ePrev: TEdge, pt: IntPoint, polyType: PolyType): void; + SetDx(e: TEdge): void; + AddBoundsToLML(e: TEdge): TEdge; + InsertLocalMinima(newLm: LocalMinima): void; + PopLocalMinima(): void; + SwapX(e: TEdge): void; + Reset(): void; + GetBounds(): IntRect; + + } + + export class Clipper extends ClipperBase { + m_PolyOuts: TEdge | ArrayLike; + m_ClipType: ClipType; + m_Scanbeam: Scanbeam; + m_ActiveEdges: TEdge; + m_SortedEdges: TEdge; + m_intersectnodes: IntersectNode; + m_ExecuteLocked: boolean; + m_ClipFillType: PolyFillType; + m_SubjFillType: PolyFillType; + m_Joins: ArrayLike; + m_HorizJoins: ArrayLike; + m_ReverseOutput: boolean; + m_UsingExPolygons: boolean; + DoublePoint: Function; + PolyOffsetBuilder: Function; + + DisposeScanbeamList(): void; + get_ReverseSolution(): boolean; + set_ReverseSolution(value: boolean): boolean; + InsertScanbeam(Y: number): void; + Execute(clipType: ClipType, solution: ArrayLike | ExPolygon): boolean; + Execute(clipType: ClipType, solution: ArrayLike | ExPolygon, subjFillType: PolyFillType, clipFillType: PolyFillType): boolean; + PolySort(or1: OutRec, or2: OutRec): number; + FindAppendLinkEnd(outRec: OutRec): OutRec; + FixHoleLinkage(outRec: OutRec): void; + ExecuteInternal(): boolean; + PopScanbeam(): number; + DisposeOutRec(index: number): void; + DisposeOutPts(pp: OutPt): void; + AddJoin(e1: TEdge, e2: TEdge, e1OutIdx: number, e2OutIdx: number): void; + AddHorzJoin(e: TEdge, idx: number): void; + InsertLocalMinimaIntoAEL(botY: number): void; + InsertEdgeIntoAEL(edge: TEdge): void; + E2InsertsBeforeE1(e1: TEdge, e2: TEdge): boolean; + IsEvenOddFillType(edge: TEdge): boolean; + IsEvenOddAltFillType(edge: TEdge): boolean; + IsContributing(edge: TEdge): boolean; + SetWindingCount(edge: TEdge): void; + AddEdgeToSEL(edge: TEdge): void; + CopyAELToSEL(): void; + SwapPositionsInAEL(edge1: TEdge, edge2: TEdge): void; + SwapPositionsInSEL(edge1: TEdge, edge2: TEdge): void; + AddLocalMaxPoly(e1: TEdge, e2: TEdge, pt: OutPt): void; + AddLocalMinPoly(e1: TEdge, e2: TEdge, pt: OutPt): void; + CreateOutRec(): OutRec; + AddOutPt(e: TEdge, pt: IntPoint): void; + SwapPoints(pt1: IntPoint, pt2: IntPoint): void; + GetOverlapSegment(pt1a: IntPoint, pt1b: IntPoint, pt2a: IntPoint, pt2b: IntPoint, pt1: IntPoint, pt2: IntPoint): boolean; + FindSegment(pp: IntPoint, pt1: IntPoint, pt2: IntPoint): boolean; + Pt3IsBetweenPt1AndPt2(pt1: boolean, pt2: boolean, pt3: boolean): OutPt; + InsertPolyPtBetween(p1: OutPt, p2: OutPt, pt: OutPt): OutPt; + SetHoleState(e: TEdge, outRec: OutRec): void; + GetDx(pt1: IntPoint, pt2: IntPoint): number; + FirstIsBottomPt(btmPt1: OutPt, btmPt2: OutPt): boolean; + GetBottomPt(pp: OutPt): OutPt; + GetLowermostRec(outRec1: OutRec, outRec2: OutRec): OutRec; + Param1RightOfParam2(outRec1: OutRec, outRec2: OutRec): boolean; + AppendPolygon(e1: TEdge, e2: TEdge): void; + ReversePolyPtLinks(pp: OutPt): void; + SwapSides(edge1: TEdge, edge2: TEdge): void; + SwapPolyIndexes(edge1: TEdge, edge2: TEdge): void; + DoEdge1(edge1: TEdge, edge2: TEdge, pt: OutPt): void; + DoEdge2(edge1: TEdge, edge2: TEdge, pt: OutPt): void; + DoBothEdges(edge1: TEdge, edge2: TEdge, pt: OutPt): void; + IntersectEdges(e1: TEdge, e2: TEdge, pt: OutPt, protects: Protects): void; + DeleteFromAEL(e: TEdge): void; + DeleteFromSEL(e: TEdge): void; + UpdateEdgeIntoAEL(e: TEdge): void; + ProcessHorizontals(): void; + ProcessHorizontal(horzEdge: TEdge): void; + IsTopHorz(horzEdge: TEdge, XPos: IntPoint): boolean; + GetNextInAEL(e: TEdge, Direction: TEdge): TEdge; + IsMinima(e: TEdge): boolean; + IsMaxima(e: TEdge, Y: number): boolean; + IsIntermediate(e: TEdge, Y: number): boolean; + GetMaximaPair(e: TEdge): TEdge; + ProcessIntersections(botY: number, topY: number): boolean; + BuildIntersectList(botY: number, topY: number): void; + FixupIntersections(): boolean; + ProcessIntersectList(): void; + Round(a: number): number; + TopX(edge: TEdge, currentY: number): number; + AddIntersectNode(e1: TEdge, e2: TEdge, pt: IntPoint): void; + ProcessParam1BeforeParam2(node1: IntersectNode, node2: IntersectNode): boolean; + SwapIntersectNodes(int1: IntersectNode, int2: IntersectNode): void; + IntersectPoint(edge1: TEdge, edge2: TEdge, ip: IntPoint): boolean; + DisposeIntersectNodes(): void; + ProcessEdgesAtTopOfScanbeam(topY: number): void; + DoMaxima(e: TEdge, topY: number): void; + ReversePolygons(polys: Polygons): void; + Orientation(poly: Polygon): boolean; + PointCount(pts: ArrayLike): number; + BuildResult(polyg: Polygon): void; + BuildResultEx(polyg: ExPolygon): void; + FixupOutPolygon(outRec: OutPt): void; + JoinPoints(j: JoinRec, p1: IntPoint, p2: IntPoint): boolean; + FixupJoinRecs(j: JoinRec, pt: JoinRec, startIdx: number): void; + JoinCommonEdges(): void; + FullRangeNeeded(pts: ArrayLike): boolean; + Area(poly: Polygon): number; + Area(outRec: OutRec, UseFull64BitRange: boolean): number; + BuildArc(pt: IntPoint, a1: IntPoint, a2: IntPoint, r: number): Polygon; + GetUnitNormal(pt1: IntPoint, pt2: IntPoint): DoublePoint; + OffsetPolygons(poly: Polygon, delta: number, jointype: JoinType, MiterLimit: number, AutoFix: boolean): ArrayLike>; + SimplifyPolygon(poly: Polygon, fillType: PolyFillType): Polygon; + SimplifyPolygons(polys: Polygons, fillType: PolyFillType): Polygons; + + + } + export class DoublePoint { + X: number; + Y: number; + constructor(x: number, y: number); + } + + export class PolyOffsetBuilder { + pts: Polygons; + currentPoly: Polygon; + normals: ArrayLike; + delta: number; + m_R: number; + m_i: number; + m_j: number; + m_k: number; + botPt: PolyOffsetBuilder; + + constructor(pts: Polygons, solution: { value: Polygons }, delta: number, jointype: JoinType, MiterLimit: number, AutoFix: boolean); + UpdateBotPt(pt: IntPoint): boolean; + AddPoint(pt: IntPoint): void; + DoSquare(mul: number): void; + DoMiter(): void; + DoRound(): void; + } + export function Error(message: string): void; + export function Clone(polygon: ArrayLike | ArrayLike>): ArrayLike | ArrayLike>; + export function Clean(polygon: ArrayLike | ArrayLike>, delta: number): ArrayLike | ArrayLike>; + export function Lighten(polygon: ArrayLike | ArrayLike>, tolerance: number): ArrayLike | ArrayLike>; + + +} + diff --git a/sat/sat-tests.ts b/sat/sat-tests.ts new file mode 100644 index 0000000000..df453d4e9c --- /dev/null +++ b/sat/sat-tests.ts @@ -0,0 +1,23 @@ +/// +class SatTest{ + public vectorTest(){ + let v1: SAT.Vector = new SAT.Vector(10, 10); + console.log("def: v1 - " + v1.x.toString() + v1.y.toString()); + let v2: SAT.Vector = new SAT.Vector(20,20); + console.log("def: v2 - " + v2.x.toString() + v1.y.toString()); + let v3: SAT.Vector = new SAT.Vector(30,30); + console.log("def: v3 -" + v3.x.toString() + v1.y.toString()); + v2.copy(v1); + console.log("copy: v2 - " + v2.x.toString() + v2.y.toString()); + v3 = v1.clone(); + console.log("clone: v3 - " + v3.x.toString() + v3.y.toString()); + v3.perp(); + console.log("perp: v3 - " + v3.x.toString() + v3.y.toString()); + + } + +} + +let test = new SatTest; + +test.vectorTest(); \ No newline at end of file diff --git a/sat/sat.d.ts b/sat/sat.d.ts new file mode 100644 index 0000000000..64021b5899 --- /dev/null +++ b/sat/sat.d.ts @@ -0,0 +1,142 @@ +// Type definitions for sat.js +// Project: https://github.com/jriecken/sat-js +// Definitions by: Hou Chunlei +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +declare module SAT { + + /** + * This is a simple 2D vector/point class,Vector has two parameters {x},{y}. + */ + export class Vector { + /** + * @class Vector has two properties + * @param {number} x The x-coordinate of the Vector. + * @param {number} y The y-coordinate of the Vector. + */ + constructor(x: number, y: number); + + x: number; + y: number; + + copy(other: Vector): Vector; + clone(): Vector; + perp(): Vector; + rotate(angle: number): Vector; + reverse(): Vector; + normalize(): Vector; + add(other: Vector): Vector; + sub(other: Vector): Vector; + scale(x: number, y: number): Vector; + project(other: Vector): Vector; + projectN(other: Vector): Vector; + reflect(axis: Vector): Vector; + reflectN(axis: Vector): Vector; + dot(other: Vector): number; + len2(): number; + len(): number; + } + /** + * This is simple circle with a center {pos} position and radius {r}. + */ + export class Circle { + constructor(pos: Vector, r: number); + + pos: Vector; + r: number; + } + export class Polygon { + constructor(pos: Vector, points: Vector[]); + + pos: Vector; + points: Vector[]; + angle: number; + offset: Vector; + calcPoints: Vector[]; + edges: Vector[]; + normals: Vector[]; + + setPoints(points: Vector[]): Polygon; + setAngle(angle: number): Polygon; + setOffset(offset: Vector): Polygon; + recalc(): Polygon; + rotate(angle: number): Polygon; + translate(x: number, y: number): Polygon; + getAABB(): Polygon; + + } + export class Box { + constructor(pos: Vector, width: number, height: number); + + pos: Vector; + w: number; + h: number; + + toPolygon(): Polygon; + } + export class Response { + constructor(); + + a: any; + b: any; + overlap: number; + overlapN: Vector; + overlapV: Vector; + aInB: boolean; + bInA: boolean; + + clear(): Response; + } + + /** + * @function {pointInCircle} checks whether a given point {p} is inside the specified circle {c}. + * @param {Vector} p given a point to checks. + * @param {Circle} c check with a specified circle + * @return {boolean} return {true} if there is a collision. {false} otherwise. + */ + export function pointInCircle(p: Vector, c: Circle): boolean; + /** + * @function {pointInPolygon} checks whether a given point [p] is inside a specified convex polygon. + * @param {Vector} p given a point to check. + * @param {Polygon} poly check with a spcified convex polygon. + * @return {boolean} return {true} if there is a collision. {false} otherwise. + */ + export function pointInPolygon(p: Vector, poly: Polygon): boolean; + /** + * @function {testCicleCircle} tests a collision between two {Circle}s, {a} and {b}. + * if a {response} is to be calculated in the event of a collision, pass in a cleared {Response} object. + * @param {Circle} a specified circle a to tests. + * @param {Circle} b spacified circle b to tests. + * @param {Response} response specified the result of a collision between two circle. + * @return {boolean} return {true} if there is a collision. {false} otherwise. + */ + export function testCircleCircle(a: Circle, b: Circle, response?: Response): boolean; + /** + * @function {testPolygonCicle} tests a collision between a {Polygon} and a {Circle}. if a response is to + * be calculated in the event of a collision, pass in a cleared {Response} object. + * @param {Polygon} polygon specified a Polygon to tests a collision. + * @param {Circle} circle specified a Circle to tests a collision. + * @param {Response} response specified the result of a collision between a {Polygon} and a {Circle}. + * @return {boolean} return {true} if there is a collision. {false} otherwise. + */ + export function testPolygonCircle(polygon: Polygon, circle: Circle, response?: Response): boolean; + /** + * @function {testCirclePolygon} tests a collision between a {Circle} and a {Polygon}. if a response is to + * be calculated in the event of a collision, pass in a cleared {Response} object. + * @param {Circle} circle specified a {Circle} to tests a collision. + * @param {Polygon} polygon specified a {Polygon} to tests a collision. + * @param {Response} response specified the result of a collision between a {Circle} and a {Polygon}. + * @return {boolean} return {true} if there is a collision. {false} otherwise. + */ + export function testCirclePolygon(circle: Circle, polygon: Polygon, response?: Response): boolean; + /** + * @function {testPolygonPolygon} tests whether two polygons {a} and {b} collide. + * if a response is to be calculated in the event of a collision, pass in a cleared {Response} object. + * @param {Polygon} a specified a {Polygon} {a} to test a collision. + * @param {Polygon} b specified a {Polygon} {b} to test a collision. + * @param {Response} response specified the result of a collision between two {Polygon}s. + * @return {boolean} return {true} if there is a collision. {false} otherwise. + */ + export function testPolygonPolygon(a: Polygon, b: Polygon, response?: Response): boolean; + +}