@escapace/minimum-perimeter-triangle 0.2.5 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { Line } from './line';
2
2
  import { Vec2 } from './vec2';
3
- export interface Circle {
3
+ interface Circle {
4
4
  centre: Vec2;
5
5
  r: number;
6
6
  }
@@ -10,26 +10,27 @@ export interface Circle {
10
10
  * in this case they must point in the same direction
11
11
  */
12
12
  export declare class Wedge {
13
+ readonly isDegenerate: boolean;
13
14
  readonly leftArm: Line;
14
15
  readonly rightArm: Line;
15
- readonly isDegenerate: boolean;
16
16
  private constructor();
17
- static new(leftArm: Line, rightArm: Line, err: number): Wedge | null;
18
- formTriangle(line: Line, err: number): boolean;
19
- looselyContains(p: Vec2, err: number): boolean;
20
- strictlyContains(p: Vec2, err: number): boolean;
21
- private fit_Dp;
17
+ static new(leftArm: Line, rightArm: Line, error: number): Wedge | null;
22
18
  private fit_Dl;
23
- private fit_NDp;
19
+ private fit_Dp;
24
20
  private fit_NDl;
25
- fitCircles(element: Vec2, err: number): Array<{
21
+ private fit_NDp;
22
+ fitCircles(element: Vec2, error: number): Array<{
26
23
  circle: Circle;
27
24
  tangent: Line;
28
25
  }> | null;
29
- fitCircles(element: Line, err: number): Array<{
26
+ fitCircles(element: Line, error: number): Array<{
30
27
  circle: Circle;
31
28
  tangentParameter: number;
32
29
  }> | null;
30
+ formTriangle(line: Line, error: number): boolean;
31
+ looselyContains(p: Vec2, error: number): boolean;
32
+ strictlyContains(p: Vec2, error: number): boolean;
33
33
  toString(): string;
34
34
  }
35
+ export {};
35
36
  //# sourceMappingURL=inscribe.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inscribe.d.ts","sourceRoot":"","sources":["../../src/inscribe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAQ,MAAM,QAAQ,CAAA;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAE7B,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,IAAI,CAAA;IACZ,CAAC,EAAE,MAAM,CAAA;CACV;AAED;;;;GAIG;AACH,qBAAa,KAAK;IAChB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;IACvB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAE9B,OAAO;IAMP,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI;IA2DpE,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAyB9C,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAuB9C,gBAAgB,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IA+B/C,OAAO,CAAC,MAAM;IAgEd,OAAO,CAAC,MAAM;IAoDd,OAAO,CAAC,OAAO;IA2Ef,OAAO,CAAC,OAAO;IAwGf,UAAU,CACR,OAAO,EAAE,IAAI,EACb,GAAG,EAAE,MAAM,GACV,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,IAAI,CAAA;KAAE,CAAC,GAAG,IAAI;IAClD,UAAU,CACR,OAAO,EAAE,IAAI,EACb,GAAG,EAAE,MAAM,GACV,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;IAe7D,QAAQ,IAAI,MAAM;CAMnB"}
1
+ {"version":3,"file":"inscribe.d.ts","sourceRoot":"","sources":["../../src/inscribe.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAQ,MAAM,QAAQ,CAAA;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAE7B,UAAU,MAAM;IACd,MAAM,EAAE,IAAI,CAAA;IACZ,CAAC,EAAE,MAAM,CAAA;CACV;AAED;;;;GAIG;AACH,qBAAa,KAAK;IAChB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;IAEvB,OAAO;IAMP,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI;IA4DtE,OAAO,CAAC,MAAM;IAkDd,OAAO,CAAC,MAAM;IA6Dd,OAAO,CAAC,OAAO;IAgHf,OAAO,CAAC,OAAO;IAqEf,UAAU,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,IAAI,CAAA;KAAE,CAAC,GAAG,IAAI;IAEzF,UAAU,CACR,OAAO,EAAE,IAAI,EACb,KAAK,EAAE,MAAM,GACZ,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;IAc7D,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAwBhD,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAqBhD,gBAAgB,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAsBjD,QAAQ,IAAI,MAAM;CAMnB"}
@@ -1,23 +1,21 @@
1
- import { Vec2 } from './vec2';
1
+ import type { Vec2 } from './vec2';
2
2
  export declare enum Side {
3
+ Left = 1,
3
4
  Right = -1,
4
- Top = 0,
5
- Left = 1
5
+ Top = 0
6
6
  }
7
7
  export declare class Line {
8
- readonly start: Vec2;
9
- readonly end: Vec2;
10
8
  readonly delta: Vec2;
9
+ readonly end: Vec2;
10
+ readonly start: Vec2;
11
11
  constructor(start: Vec2, end: Vec2);
12
- /**
13
- * Length of a line is the length between its two defining points
14
- */
15
- get length(): number;
16
- evaluate(t: number): Vec2;
12
+ closestPoint(p: Vec2): Vec2;
13
+ closestPointParam(p: Vec2): number;
17
14
  distanceToPoint(p: Vec2): number;
18
- pointOnSide(p: Vec2, err?: number): number;
19
- pointOnTop(p: Vec2, err: number): boolean;
20
- overlaps(that: Line, err: number): boolean;
15
+ evaluate(t: number): Vec2;
16
+ intersectionParameter(that: Line, error: number): number | null;
17
+ intersectionPoint(that: Line, error: number): Vec2 | null;
18
+ overlaps(that: Line, error: number): boolean;
21
19
  /**
22
20
  * If alpha is less than deviationFromZeroAngle, the 2 lines are
23
21
  * considered parallel.
@@ -28,9 +26,11 @@ export declare class Line {
28
26
  * /
29
27
  */
30
28
  parallel(that: Line, deviationFromZeroAngle: number): boolean;
31
- intersectionParameter(that: Line, err: number): number | null;
32
- closestPointParam(p: Vec2): number;
33
- closestPoint(p: Vec2): Vec2;
34
- intersectionPoint(that: Line, err: number): Vec2 | null;
29
+ pointOnSide(p: Vec2, error?: number): number;
30
+ pointOnTop(p: Vec2, error: number): boolean;
31
+ /**
32
+ * Length of a line is the length between its two defining points
33
+ */
34
+ get length(): number;
35
35
  }
36
36
  //# sourceMappingURL=line.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"line.d.ts","sourceRoot":"","sources":["../../src/line.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAE7B,oBAAY,IAAI;IACd,KAAK,KAAK;IACV,GAAG,IAAI;IACP,IAAI,IAAI;CACT;AAED,qBAAa,IAAI;IACf,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAA;IAClB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAA;gBAER,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI;IAMlC;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAIzB,eAAe,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM;IAOhC,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,SAAI,GAAG,MAAM;IAQrC,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAI1C;;;;;;;;OAQG;IACH,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,sBAAsB,EAAE,MAAM,GAAG,OAAO;IAS7D,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAS7D,iBAAiB,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM;IAIlC,YAAY,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI;IAI3B,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;CAIxD"}
1
+ {"version":3,"file":"line.d.ts","sourceRoot":"","sources":["../../src/line.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAElC,oBAAY,IAAI;IACd,IAAI,IAAI;IACR,KAAK,KAAK;IACV,GAAG,IAAI;CACR;AAED,qBAAa,IAAI;IACf,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAA;IAClB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAA;gBAER,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI;IAMlC,YAAY,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI;IAI3B,iBAAiB,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM;IAIlC,eAAe,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM;IAIhC,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAIzB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAS/D,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAKzD,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAI5C;;;;;;;;OAQG;IACH,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,sBAAsB,EAAE,MAAM,GAAG,OAAO;IAM7D,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,SAAI,GAAG,MAAM;IAQvC,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAI3C;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;CACF"}
@@ -1,23 +1,23 @@
1
1
  export declare class Vec2 {
2
- private readonly _x;
3
- private readonly _y;
4
- private _normSquared;
5
2
  private _norm;
6
3
  private _normalized;
4
+ private _normSquared;
5
+ private readonly _x;
6
+ private readonly _y;
7
7
  constructor(x: number, y: number);
8
- times(s: number): Vec2;
8
+ cross(that: Vec2): number;
9
+ dot(that: Vec2): number;
10
+ equals(that: Vec2, error: number): boolean;
11
+ minus(that: Vec2): Vec2;
12
+ normal(): Vec2;
9
13
  over(s: number): Vec2;
10
- get x(): number;
11
- get y(): number;
12
14
  plus(that: Vec2): Vec2;
13
- minus(that: Vec2): Vec2;
14
- get normSquared(): number;
15
+ times(s: number): Vec2;
16
+ toString(): string;
15
17
  get norm(): number;
16
18
  get normalized(): Vec2;
17
- dot(that: Vec2): number;
18
- cross(that: Vec2): number;
19
- equals(that: Vec2, err: number): boolean;
20
- normal(): Vec2;
21
- toString(): string;
19
+ get normSquared(): number;
20
+ get x(): number;
21
+ get y(): number;
22
22
  }
23
23
  //# sourceMappingURL=vec2.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vec2.d.ts","sourceRoot":"","sources":["../../src/vec2.ts"],"names":[],"mappings":"AACA,qBAAa,IAAI;IACf,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAQ;IAC3B,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAQ;IAE3B,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,WAAW,CAAkB;gBAEzB,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAKhC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAItB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAIrB,IAAI,CAAC,IAAI,MAAM,CAEd;IAED,IAAI,CAAC,IAAI,MAAM,CAEd;IAED,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAItB,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAIvB,IAAI,WAAW,IAAI,MAAM,CAIxB;IAED,IAAI,IAAI,IAAI,MAAM,CAIjB;IAED,IAAI,UAAU,IAAI,IAAI,CAIrB;IAED,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAIvB,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAIzB,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAOxC,MAAM,IAAI,IAAI;IAId,QAAQ,IAAI,MAAM;CAGnB"}
1
+ {"version":3,"file":"vec2.d.ts","sourceRoot":"","sources":["../../src/vec2.ts"],"names":[],"mappings":"AACA,qBAAa,IAAI;IACf,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,WAAW,CAAkB;IAErC,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAQ;IAC3B,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAQ;gBAEf,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAKhC,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAIzB,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAIvB,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAO1C,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAIvB,MAAM,IAAI,IAAI;IAId,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAIrB,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAItB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAItB,QAAQ,IAAI,MAAM;IAIlB,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,UAAU,IAAI,IAAI,CAIrB;IAED,IAAI,WAAW,IAAI,MAAM,CAIxB;IAED,IAAI,CAAC,IAAI,MAAM,CAEd;IAED,IAAI,CAAC,IAAI,MAAM,CAEd;CACF"}
package/package.json CHANGED
@@ -1,69 +1,63 @@
1
1
  {
2
2
  "name": "@escapace/minimum-perimeter-triangle",
3
3
  "description": "",
4
- "version": "0.2.5",
4
+ "version": "0.2.6",
5
5
  "author": {
6
6
  "name": "escapace",
7
7
  "email": "opensource@escapace.com"
8
8
  },
9
9
  "bugs": "https://github.com/escapace/minimum-perimeter-triangle/issues",
10
10
  "devDependencies": {
11
- "@commitlint/cli": "17.7.1",
12
- "@commitlint/config-conventional": "17.7.0",
13
- "@ls-lint/ls-lint": "2.1.0",
14
- "@types/chai": "4.3.6",
15
- "@types/mocha": "10.0.1",
16
- "@types/node": "20.6.4",
17
- "@typescript-eslint/eslint-plugin": "6.7.2",
18
- "@typescript-eslint/parser": "6.7.2",
19
- "c8": "8.0.1",
20
- "chai": "4.3.8",
21
- "esbuild": "0.19.3",
22
- "eslint": "8.50.0",
23
- "eslint-config-escapace": "3.18.1",
24
- "eslint-config-prettier": "9.0.0",
25
- "eslint-plugin-editorconfig": "4.0.3",
26
- "eslint-plugin-no-null": "1.0.2",
27
- "execa": "8.0.1",
28
- "fast-glob": "3.3.1",
29
- "fs-extra": "11.1.1",
30
- "husky": "8.0.3",
31
- "is-ci": "3.0.1",
32
- "lint-staged": "14.0.1",
33
- "mocha": "10.2.0",
34
- "prettier": "3.0.3",
35
- "prettier-config-escapace": "1.0.6",
36
- "semver": "7.5.4",
37
- "syncpack": "11.2.1",
38
- "ts-node": "10.9.1",
39
- "typescript": "5.2.2"
11
+ "@commitlint/cli": "19.6.0",
12
+ "@commitlint/config-conventional": "19.6.0",
13
+ "@escapace/pnpm-pack": "0.5.3",
14
+ "@ls-lint/ls-lint": "2.2.3",
15
+ "@vitest/coverage-v8": "2.1.8",
16
+ "eslint": "9.17.0",
17
+ "eslint-config-escapace": "5.4.0",
18
+ "esroll": "0.3.0",
19
+ "knip": "5.40.0",
20
+ "lefthook": "1.9.2",
21
+ "prettier": "3.4.2",
22
+ "prettier-config-escapace": "1.2.1",
23
+ "syncpack": "13.0.0",
24
+ "tsx": "4.19.2",
25
+ "typescript": "5.7.2",
26
+ "vitest": "2.1.8"
40
27
  },
41
28
  "engines": {
42
- "node": ">=18.18.0",
43
- "pnpm": ">=8.7.6"
29
+ "pnpm": ">=9.14.4"
44
30
  },
45
31
  "exports": {
46
32
  ".": {
47
- "import": "./lib/esm/index.mjs",
48
- "types": "./lib/types/index.d.ts"
33
+ "types": "./lib/types/index.d.ts",
34
+ "import": "./lib/neutral/index.js"
49
35
  }
50
36
  },
51
37
  "files": [
52
- "lib/esm",
38
+ "lib/neutral",
53
39
  "lib/types"
54
40
  ],
55
- "homepage": "https://github.com/escapace/minimum-perimeter-triangle",
41
+ "homepage": "https://github.com/escapace/minimum-perimeter-triangle#readme",
56
42
  "license": "MPL-2.0",
57
- "module": "lib/esm/index.mjs",
43
+ "module": "lib/neutral/index.js",
58
44
  "private": false,
59
- "repository": "escapace/minimum-perimeter-triangle.git",
45
+ "publishConfig": {
46
+ "access": "public",
47
+ "provenance": true
48
+ },
49
+ "repository": "escapace/minimum-perimeter-triangle",
60
50
  "sideEffects": false,
61
51
  "type": "module",
62
52
  "types": "lib/types/index.d.ts",
63
53
  "scripts": {
64
- "build": "node ./scripts/build.mjs",
65
- "lint": "ls-lint && eslint 'src/**/*.{js,mjs,cjs,ts,mts,cts}'",
66
- "test": "node ./scripts/test.mjs && c8 mocha --enable-source-maps 'lib/tests/**/*.spec.js'",
54
+ "build": "tsx scripts/build.ts",
55
+ "format": "syncpack format && eslint --no-warn-ignored --fix && prettier -uw .",
56
+ "lint": "ls-lint --config .ls-lint.yaml && knip --no-config-hints && eslint",
57
+ "ls-lint": "ls-lint --config .ls-lint.yaml",
58
+ "pack": "pnpm-pack package --pack-destination lib",
59
+ "syncpack": "syncpack fix-mismatches && syncpack set-semver-ranges && syncpack format",
60
+ "test": "vitest --no-watch --coverage",
67
61
  "typecheck": "tsc --noEmit"
68
62
  }
69
63
  }
package/lib/esm/index.mjs DELETED
@@ -1,399 +0,0 @@
1
- // src/line.ts
2
- var Line = class {
3
- start;
4
- end;
5
- delta;
6
- constructor(start, end) {
7
- this.start = start, this.end = end, this.delta = end.minus(start);
8
- }
9
- /**
10
- * Length of a line is the length between its two defining points
11
- */
12
- get length() {
13
- return this.delta.norm;
14
- }
15
- evaluate(t) {
16
- return this.start.plus(this.delta.times(t));
17
- }
18
- distanceToPoint(p) {
19
- return Math.abs(p.cross(this.delta) - this.start.cross(this.end)) / this.delta.norm;
20
- }
21
- pointOnSide(p, err = 0) {
22
- let num = this.start.cross(this.end) - p.cross(this.delta);
23
- return num === 0 || Math.abs(num) / this.delta.norm < err ? 0 /* Top */ : num > 0 ? 1 /* Left */ : -1 /* Right */;
24
- }
25
- pointOnTop(p, err) {
26
- return this.pointOnSide(p, err) === 0 /* Top */;
27
- }
28
- overlaps(that, err) {
29
- return this.pointOnTop(that.start, err) && this.pointOnTop(that.end, err);
30
- }
31
- /**
32
- * If alpha is less than deviationFromZeroAngle, the 2 lines are
33
- * considered parallel.
34
- * _______________________________
35
- * alpha (/
36
- * /
37
- * /
38
- * /
39
- */
40
- parallel(that, deviationFromZeroAngle) {
41
- let d = Math.abs(this.delta.cross(that.delta));
42
- return d === 0 || d < this.length * this.length * Math.sin(deviationFromZeroAngle);
43
- }
44
- intersectionParameter(that, err) {
45
- let d = this.delta.cross(that.delta);
46
- if (d === 0 || Math.abs(d) < err)
47
- return null;
48
- let dStart = this.start.minus(that.start);
49
- return that.delta.cross(dStart) / d;
50
- }
51
- closestPointParam(p) {
52
- return this.delta.dot(p.minus(this.start)) / this.delta.normSquared;
53
- }
54
- closestPoint(p) {
55
- return this.evaluate(this.closestPointParam(p));
56
- }
57
- intersectionPoint(that, err) {
58
- let t = this.intersectionParameter(that, err);
59
- return t === null ? null : this.evaluate(t);
60
- }
61
- };
62
-
63
- // src/vec2.ts
64
- var Vec2 = class _Vec2 {
65
- _x;
66
- _y;
67
- _normSquared;
68
- _norm;
69
- _normalized;
70
- constructor(x, y) {
71
- this._x = x, this._y = y;
72
- }
73
- times(s) {
74
- return new _Vec2(this._x * s, this._y * s);
75
- }
76
- over(s) {
77
- return new _Vec2(this._x / s, this._y / s);
78
- }
79
- get x() {
80
- return this._x;
81
- }
82
- get y() {
83
- return this._y;
84
- }
85
- plus(that) {
86
- return new _Vec2(this._x + that._x, this._y + that._y);
87
- }
88
- minus(that) {
89
- return new _Vec2(this._x - that._x, this._y - that._y);
90
- }
91
- get normSquared() {
92
- return this._normSquared === void 0 ? this._normSquared = this.dot(this) : this._normSquared;
93
- }
94
- get norm() {
95
- return this._norm === void 0 ? this._norm = Math.sqrt(this.normSquared) : this._norm;
96
- }
97
- get normalized() {
98
- return this._normalized === void 0 ? this._normalized = this.over(this.norm) : this._normalized;
99
- }
100
- dot(that) {
101
- return this._x * that._x + this._y * that._y;
102
- }
103
- cross(that) {
104
- return this._x * that._y - this._y * that._x;
105
- }
106
- equals(that, err) {
107
- return err === 0 ? this.x === that.x && this.y === that.y : this.minus(that).normSquared < err * err;
108
- }
109
- normal() {
110
- return new _Vec2(this._y, -this._x);
111
- }
112
- toString() {
113
- return `(${this.x}, ${this.y})`;
114
- }
115
- };
116
-
117
- // src/inscribe.ts
118
- var Wedge = class _Wedge {
119
- leftArm;
120
- rightArm;
121
- isDegenerate;
122
- constructor(leftArm, rightArm, isDegenerate = !1) {
123
- this.leftArm = leftArm, this.rightArm = rightArm, this.isDegenerate = isDegenerate;
124
- }
125
- static new(leftArm, rightArm, err) {
126
- if (leftArm === null || rightArm === null || err !== 0 && leftArm.overlaps(rightArm, err))
127
- return null;
128
- let deviationFromZeroAngle = 0.1 / (leftArm.length * rightArm.length);
129
- if (leftArm.parallel(rightArm, deviationFromZeroAngle)) {
130
- let p = new Line(leftArm.evaluate(0.5), rightArm.evaluate(0.5)).evaluate(0.5), sideLeft = leftArm.pointOnSide(p, err), sideRight = rightArm.pointOnSide(p, err);
131
- if (sideLeft === 0 /* Top */ || sideRight === 0 /* Top */)
132
- throw new Error();
133
- return sideLeft !== sideRight ? new _Wedge(leftArm, rightArm, !0) : new _Wedge(leftArm, new Line(rightArm.end, rightArm.start));
134
- }
135
- let tLA = leftArm.intersectionParameter(rightArm, 0), tRA = rightArm.intersectionParameter(leftArm, 0);
136
- if (tLA === 0.5 || tRA === 0.5)
137
- return null;
138
- let W = leftArm.evaluate(tLA), eLA = tLA < 1 - tLA ? leftArm.end : leftArm.start, eRA = tRA < 1 - tRA ? rightArm.end : rightArm.start;
139
- return new _Wedge(new Line(W, eLA), new Line(W, eRA));
140
- }
141
- formTriangle(line, err) {
142
- if (this.leftArm.parallel(line, 0.1 / (this.leftArm.length * line.length)) || this.rightArm.parallel(line, 0.1 / (this.rightArm.length * line.length)))
143
- return !1;
144
- let A = line.intersectionPoint(this.leftArm, 0), B = line.intersectionPoint(this.rightArm, 0);
145
- if (this.isDegenerate)
146
- return !A.equals(B, err);
147
- let C = this.leftArm.intersectionPoint(this.rightArm, 0);
148
- return !C.equals(A, err) && !C.equals(B, err) && !A.equals(B, err) && !new Line(A, B).pointOnTop(C, err);
149
- }
150
- looselyContains(p, err) {
151
- let pLeft = this.leftArm.pointOnSide(p, err), pRight = this.rightArm.pointOnSide(p, err);
152
- return pLeft === 0 /* Top */ || pRight === 0 /* Top */ ? !0 : pLeft === pRight ? !1 : this.isDegenerate ? (
153
- // degenerate + different sides => true
154
- !0
155
- ) : (
156
- // 2. (Because the arms intersect)
157
- // Projection params of the point onto the arms must be larger than 0
158
- this.leftArm.closestPointParam(p) >= 0 && this.rightArm.closestPointParam(p) >= 0
159
- );
160
- }
161
- strictlyContains(p, err) {
162
- let pLeft = this.leftArm.pointOnSide(p, err), pRight = this.rightArm.pointOnSide(p, err);
163
- return pLeft === 0 /* Top */ || pRight === 0 /* Top */ || pLeft === pRight ? !1 : this.isDegenerate ? (
164
- // degenerate + different sides => true
165
- !0
166
- ) : (
167
- // 2. (Because the arms intersect)
168
- // Projection params of the point onto the arms must be larger than 0
169
- this.leftArm.closestPointParam(p) >= 0 && this.rightArm.closestPointParam(p) >= 0
170
- );
171
- }
172
- // While fitting circles into a wedge
173
- // There are four distinct cases:
174
- // 1. Wedge is degenerate and additional element is a point
175
- // 2. Wedge is degenerate and additional element is a line
176
- // 3. Wedge is non-degenerate and additional element is a point
177
- // 4. Wedge is non-degenerate and additional element is a line
178
- // according to these assumptions, the following methods are named
179
- fit_Dp(p, err) {
180
- if (!this.strictlyContains(p, err))
181
- return null;
182
- let A = this.rightArm.closestPoint(p), Ap = this.leftArm.closestPoint(A), I = A.plus(Ap).over(2), r = A.minus(Ap).norm / 2, a = this.rightArm.delta.normSquared, b = I.minus(p).dot(this.rightArm.delta) * 2, c = I.minus(p).normSquared - r * r, discriminant = b * b - 4 * a * c;
183
- if (discriminant < (-10) ** -5)
184
- return null;
185
- let t = [];
186
- Math.abs(discriminant) < 10 ** -5 ? t.push(-b / (2 * a)) : (t.push((-b + Math.sqrt(discriminant)) / (2 * a)), t.push((-b - Math.sqrt(discriminant)) / (2 * a)));
187
- let result = [];
188
- return t.forEach((t0) => {
189
- let O = this.rightArm.delta.times(t0).plus(I);
190
- result.push({
191
- circle: { centre: O, r },
192
- tangent: new Line(p, p.plus(O.minus(p).normal()))
193
- });
194
- }), result;
195
- }
196
- fit_Dl(l, err) {
197
- if (!this.formTriangle(l, err))
198
- return null;
199
- let A = l.intersectionPoint(this.rightArm, 0), B = l.intersectionPoint(this.leftArm, 0), AB = new Line(A, B), Ap = this.leftArm.closestPoint(A), I = A.plus(Ap).over(2), r = A.minus(Ap).norm / 2, t1 = (AB.delta.cross(A.minus(I)) + r * AB.delta.norm) / AB.delta.cross(this.rightArm.delta), t2 = (AB.delta.cross(A.minus(I)) - r * AB.delta.norm) / AB.delta.cross(this.rightArm.delta), o1 = this.rightArm.delta.times(t1).plus(I), o2 = this.rightArm.delta.times(t2).plus(I);
200
- return [
201
- {
202
- circle: { centre: o1, r },
203
- tangentParameter: l.closestPointParam(o1)
204
- },
205
- {
206
- circle: { centre: o2, r },
207
- tangentParameter: l.closestPointParam(o2)
208
- }
209
- ];
210
- }
211
- fit_NDp(p, err) {
212
- if (!this.strictlyContains(p, err))
213
- return null;
214
- let C = this.leftArm.start, A = this.leftArm.end, B = this.rightArm.end, a = C.minus(B).norm, b = C.minus(A).norm, D = A.minus(B).times(a / (a + b)).plus(B), bisector = new Line(C, D), eA = D.minus(C).normSquared - (A.minus(C).cross(D.minus(C)) / b) ** 2, eB = D.minus(C).dot(C.minus(p)) * 2, eC = C.minus(p).normSquared, discriminant = eB * eB - 4 * eA * eC;
215
- if (discriminant < (-10) ** -5)
216
- return null;
217
- let O, r;
218
- if (Math.abs(discriminant) < 10 ** -5) {
219
- let t = -eB / (2 * eA);
220
- O = bisector.evaluate(t), r = O.minus(p).norm;
221
- } else {
222
- let t1 = (-eB + Math.sqrt(discriminant)) / (2 * eA), t2 = (-eB - Math.sqrt(discriminant)) / (2 * eA);
223
- bisector.evaluate(t1).minus(p).normSquared > bisector.evaluate(t2).minus(p).normSquared ? (O = bisector.evaluate(t1), r = bisector.evaluate(t1).minus(p).norm) : (O = bisector.evaluate(t2), r = bisector.evaluate(t2).minus(p).norm);
224
- }
225
- return [
226
- {
227
- circle: { centre: O, r },
228
- tangent: new Line(p, p.plus(O.minus(p).normal()))
229
- }
230
- ];
231
- }
232
- fit_NDl(l, err) {
233
- if (!this.formTriangle(l, err))
234
- return null;
235
- let C = this.leftArm.start, A = l.intersectionPoint(this.leftArm, 0), B = l.intersectionPoint(this.rightArm, 0), AC = new Line(A, C), BC = new Line(B, C), AB = new Line(A, B), a = AC.length, b = BC.length, c = AB.length, s = (a + b + c) / 2;
236
- if (s * (s - a) * (s - b) / (s - c) < 0)
237
- return null;
238
- let r = Math.sqrt(s * (s - a) * (s - b) / (s - c)), det = AB.delta.cross(AC.delta), lhsAll = [
239
- new Vec2(B.cross(A) + r * c, C.cross(A) + r * a),
240
- new Vec2(B.cross(A) + r * c, C.cross(A) - r * a),
241
- new Vec2(B.cross(A) - r * c, C.cross(A) + r * a),
242
- new Vec2(B.cross(A) - r * c, C.cross(A) - r * a)
243
- ], OAll = [];
244
- lhsAll.forEach((lhs) => {
245
- OAll.push(
246
- new Vec2(
247
- new Vec2(AB.delta.x, AC.delta.x).cross(lhs),
248
- new Vec2(AB.delta.y, AC.delta.y).cross(lhs)
249
- ).over(-det)
250
- );
251
- });
252
- let o = null, dists = [];
253
- for (let O of OAll) {
254
- dists.push({
255
- raw: Math.abs(BC.distanceToPoint(O) - r),
256
- norm: Math.abs(BC.distanceToPoint(O) / r - 1)
257
- });
258
- let absoluteError = Math.abs(BC.distanceToPoint(O) - r), relativeError = Math.abs(BC.distanceToPoint(O) / r - 1);
259
- if ((absoluteError < 10 ** -5 || relativeError < 10 ** -5) && AC.pointOnSide(O) !== BC.pointOnSide(O)) {
260
- o = O;
261
- break;
262
- }
263
- }
264
- let msg = "";
265
- if (o === null) {
266
- msg = "fit_NDl, centre is undefined";
267
- for (let i = 0; i < OAll.length; i++)
268
- msg += `centre: (${OAll[i].x}, ${OAll[i].y}), r: ${r}, dist raw: ${dists[i].raw}, dist norm: ${dists[i].norm}
269
- `;
270
- }
271
- if (o === null)
272
- throw new Error(msg);
273
- return [
274
- {
275
- circle: { centre: o, r },
276
- tangentParameter: l.closestPointParam(o)
277
- }
278
- ];
279
- }
280
- fitCircles(element, err) {
281
- return element instanceof Vec2 ? this.isDegenerate ? this.fit_Dp(element, err) : this.fit_NDp(element, err) : element instanceof Line ? this.isDegenerate ? this.fit_Dl((element instanceof Line, element), err) : this.fit_NDl((element instanceof Line, element), err) : null;
282
- }
283
- toString() {
284
- return `LA: ${this.leftArm.start.toString()} --> ${this.leftArm.end.toString()}
285
- RA: ${this.rightArm.start.toString()} --> ${this.rightArm.end.toString()}`;
286
- }
287
- };
288
-
289
- // src/index.ts
290
- function lineTangentToHull(line, points, halo) {
291
- let holds = !0, side = 0 /* Top */, k = 0;
292
- for (; side === 0 /* Top */ && k < points.length; )
293
- side = line.pointOnSide(points[k], halo), k++;
294
- for (let i = k; i < points.length; i++) {
295
- let testSide = line.pointOnSide(points[i], halo);
296
- if (testSide !== 0 /* Top */ && testSide !== side) {
297
- holds = !1;
298
- break;
299
- }
300
- }
301
- return { holds, side };
302
- }
303
- function findEnclosingSide(wedge, startVertex, endVertex, points, halo) {
304
- let side = null, stopVertex = startVertex, vertex = startVertex;
305
- for (; side === null && vertex > endVertex; ) {
306
- let p1 = points[vertex], p2 = points[vertex - 1], edge = new Line(p1, p2), circlesEdge = wedge.fitCircles(edge, halo);
307
- if (circlesEdge !== null) {
308
- let tangentParameter = 100;
309
- if (wedge.isDegenerate) {
310
- let sidedness = 0 /* Top */, k = 0;
311
- for (; sidedness === 0 /* Top */ && k < points.length; )
312
- sidedness = edge.pointOnSide(points[k], halo), k++;
313
- tangentParameter = edge.pointOnSide(circlesEdge[0].circle.centre) !== sidedness ? circlesEdge[0].tangentParameter : circlesEdge[1].tangentParameter;
314
- } else
315
- tangentParameter = circlesEdge[0].tangentParameter;
316
- if (tangentParameter > 0 && tangentParameter < 1) {
317
- let Y = edge.evaluate(tangentParameter), joint = wedge.leftArm.intersectionPoint(edge, halo);
318
- side = new Line(joint, Y);
319
- }
320
- }
321
- if (side === null) {
322
- let circlesPoint = wedge.fitCircles(p2, halo);
323
- if (circlesPoint !== null) {
324
- let tangent;
325
- if (wedge.isDegenerate) {
326
- let sidedness = 0 /* Top */, k = 0;
327
- for (; sidedness === 0 /* Top */ && k < points.length; )
328
- sidedness = circlesPoint[0].tangent.pointOnSide(points[k], halo), k++;
329
- tangent = circlesPoint[0].tangent.pointOnSide(
330
- circlesPoint[0].circle.centre,
331
- halo
332
- ) !== sidedness ? circlesPoint[0].tangent : circlesPoint[1].tangent;
333
- } else
334
- tangent = circlesPoint[0].tangent;
335
- if (lineTangentToHull(tangent, points, halo).holds) {
336
- let joint = wedge.leftArm.intersectionPoint(tangent, halo);
337
- side = new Line(joint, p2);
338
- }
339
- }
340
- }
341
- stopVertex = vertex, vertex--;
342
- }
343
- return side === null ? null : { side, stopVertex };
344
- }
345
- function findAntipode(points) {
346
- let farthestIndex = 0, farthestDist = 0;
347
- for (let i = 0, n = points.length; i < n; i++) {
348
- let testDist = new Line(points[0], points[n - 1]).distanceToPoint(
349
- points[i]
350
- );
351
- testDist > farthestDist && (farthestDist = testDist, farthestIndex = i);
352
- }
353
- return farthestIndex;
354
- }
355
- function minTriangleWithBase(convexHull, err, tol) {
356
- let AB, AC, n = convexHull.length, BC = new Line(convexHull[0], convexHull[n - 1]), antipodIndex = findAntipode(convexHull), baseParallel = new Line(
357
- convexHull[antipodIndex],
358
- convexHull[antipodIndex].plus(BC.delta)
359
- ), wedge = Wedge.new(BC, baseParallel, err), Pn = n - 1, Qn = antipodIndex;
360
- do {
361
- let CQinfo = findEnclosingSide(wedge, Pn, antipodIndex, convexHull, err);
362
- if (CQinfo === null)
363
- return null;
364
- ({ side: AC, stopVertex: Pn } = CQinfo), wedge = Wedge.new(wedge.leftArm, AC, err);
365
- let BPinfo = findEnclosingSide(wedge, Qn, 0, convexHull, err);
366
- if (BPinfo === null)
367
- return null;
368
- ({ side: AB, stopVertex: Qn } = BPinfo), wedge = Wedge.new(wedge.leftArm, AB, err);
369
- } while (AB.length - AC.length > tol);
370
- let A = AC.intersectionPoint(AB, 0), B = AB.start, C = AC.start;
371
- return { A, B, C };
372
- }
373
- function minTriangle(convexHull, err, tol) {
374
- if (convexHull.length < 3)
375
- return null;
376
- if (convexHull.length === 3)
377
- return { A: convexHull[0], B: convexHull[1], C: convexHull[2] };
378
- let points = convexHull.map((p) => new Vec2(p.x, p.y)), A = null, B = null, C = null, perimeter = -1, rotations = 0;
379
- for (; rotations < points.length; ) {
380
- rotations > 0 && points.push(points.shift());
381
- let triangle = minTriangleWithBase(points, err, tol);
382
- if (triangle !== null) {
383
- let { A: A1, B: B1, C: C1 } = triangle, perimeter1 = A1.minus(B1).norm + B1.minus(C1).norm + C1.minus(A1).norm;
384
- (perimeter1 < perimeter || perimeter === -1) && ([A, B, C] = [A1, B1, C1], perimeter = perimeter1);
385
- }
386
- rotations++;
387
- }
388
- return perimeter === -1 ? null : {
389
- A: { x: A.x, y: A.y },
390
- B: { x: B.x, y: B.y },
391
- C: { x: C.x, y: C.y }
392
- };
393
- }
394
- export {
395
- lineTangentToHull,
396
- minTriangle,
397
- minTriangleWithBase
398
- };
399
- //# sourceMappingURL=index.mjs.map