@tsparticles/plugin-emitters-shape-polygon 3.0.2 → 3.1.0

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,20 +1,22 @@
1
1
  import { EmitterShapeBase } from "@tsparticles/plugin-emitters";
2
+ import { degToRad } from "@tsparticles/engine";
2
3
  import { generateRandomPointOnPolygonPerimeter, generateRandomPointWithinPolygon, generateRandomPolygon, } from "./utils.js";
4
+ const half = 0.5;
3
5
  export class EmittersPolygonShape extends EmitterShapeBase {
4
6
  constructor(position, size, fill, options) {
5
7
  super(position, size, fill, options);
6
8
  this.sides = options.sides;
7
- this.angle = (options.angle * Math.PI) / 180;
8
- this.polygon = generateRandomPolygon(position, this.sides, size.width / 2, this.angle);
9
+ this.angle = degToRad(options.angle);
10
+ this.polygon = generateRandomPolygon(position, this.sides, size.width * half, this.angle);
9
11
  }
10
12
  async init() {
11
13
  }
12
14
  async randomPosition() {
13
15
  const fill = this.fill, polygon = this.polygon, res = fill ? generateRandomPointWithinPolygon(polygon) : generateRandomPointOnPolygonPerimeter(polygon);
14
- return res ? { position: res } : null;
16
+ return Promise.resolve(res ? { position: res } : null);
15
17
  }
16
18
  resize(position, size) {
17
19
  super.resize(position, size);
18
- this.polygon = generateRandomPolygon(position, this.sides, size.width / 2, this.angle);
20
+ this.polygon = generateRandomPolygon(position, this.sides, size.width * half, this.angle);
19
21
  }
20
22
  }
package/browser/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { EmittersPolygonShapeGenerator } from "./EmittersPolygonShapeGenerator.js";
2
2
  export async function loadEmittersShapePolygon(engine, refresh = true) {
3
3
  const emittersEngine = engine;
4
- emittersEngine.addEmitterShapeGenerator &&
5
- emittersEngine.addEmitterShapeGenerator("polygon", new EmittersPolygonShapeGenerator());
4
+ emittersEngine.addEmitterShapeGenerator?.("polygon", new EmittersPolygonShapeGenerator());
6
5
  await emittersEngine.refresh(refresh);
7
6
  }
package/browser/utils.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { getRandom } from "@tsparticles/engine";
2
- export function generateRandomPolygon(position, sides, radius, rotationAngle = 0) {
3
- const polygon = [], angle = (Math.PI * 2) / sides;
2
+ const double = 2, doublePI = Math.PI * double, defaultRotation = 0, maxAttempts = 100;
3
+ export function generateRandomPolygon(position, sides, radius, rotationAngle = defaultRotation) {
4
+ const polygon = [], angle = doublePI / sides;
4
5
  for (let i = 0; i < sides; i++) {
5
6
  const currentAngle = angle * i + rotationAngle;
6
7
  polygon.push({
@@ -11,7 +12,7 @@ export function generateRandomPolygon(position, sides, radius, rotationAngle = 0
11
12
  return polygon;
12
13
  }
13
14
  export function generateRandomPointWithinPolygon(polygon) {
14
- const min = { ...polygon[0] }, max = { ...polygon[0] };
15
+ const firstIndex = 0, firstPoint = polygon[firstIndex], min = { ...firstPoint }, max = { ...firstPoint };
15
16
  for (const point of polygon) {
16
17
  if (point.x < min.x) {
17
18
  min.x = point.x;
@@ -27,7 +28,7 @@ export function generateRandomPointWithinPolygon(polygon) {
27
28
  }
28
29
  }
29
30
  let randomPoint = null;
30
- for (let attempts = 0; attempts < 100; attempts++) {
31
+ for (let attempts = 0; attempts < maxAttempts; attempts++) {
31
32
  const tmpPoint = {
32
33
  x: min.x + getRandom() * (max.x - min.x),
33
34
  y: min.y + getRandom() * (max.y - min.y),
@@ -40,12 +41,13 @@ export function generateRandomPointWithinPolygon(polygon) {
40
41
  return randomPoint;
41
42
  }
42
43
  export function generateRandomPointOnPolygonPerimeter(polygon) {
43
- const sideIndex = Math.floor(getRandom() * polygon.length), startPoint = polygon[sideIndex], endPoint = polygon[(sideIndex + 1) % polygon.length], t = getRandom();
44
+ const sideIndex = Math.floor(getRandom() * polygon.length), startPoint = polygon[sideIndex], offset = 1, endPoint = polygon[(sideIndex + offset) % polygon.length], t = getRandom();
44
45
  return { x: startPoint.x + (endPoint.x - startPoint.x) * t, y: startPoint.y + (endPoint.y - startPoint.y) * t };
45
46
  }
46
47
  export function isPointInPolygon(point, polygon) {
47
48
  let inside = false;
48
- for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
49
+ const offset = 1;
50
+ for (let i = 0, j = polygon.length - offset; i < polygon.length; j = i++) {
49
51
  const pi = polygon[i], pj = polygon[j];
50
52
  const intersect = pi.y > point.y !== pj.y > point.y && point.x < ((pj.x - pi.x) * (point.y - pi.y)) / (pj.y - pi.y) + pi.x;
51
53
  if (intersect) {
@@ -2,23 +2,25 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EmittersPolygonShape = void 0;
4
4
  const plugin_emitters_1 = require("@tsparticles/plugin-emitters");
5
+ const engine_1 = require("@tsparticles/engine");
5
6
  const utils_js_1 = require("./utils.js");
7
+ const half = 0.5;
6
8
  class EmittersPolygonShape extends plugin_emitters_1.EmitterShapeBase {
7
9
  constructor(position, size, fill, options) {
8
10
  super(position, size, fill, options);
9
11
  this.sides = options.sides;
10
- this.angle = (options.angle * Math.PI) / 180;
11
- this.polygon = (0, utils_js_1.generateRandomPolygon)(position, this.sides, size.width / 2, this.angle);
12
+ this.angle = (0, engine_1.degToRad)(options.angle);
13
+ this.polygon = (0, utils_js_1.generateRandomPolygon)(position, this.sides, size.width * half, this.angle);
12
14
  }
13
15
  async init() {
14
16
  }
15
17
  async randomPosition() {
16
18
  const fill = this.fill, polygon = this.polygon, res = fill ? (0, utils_js_1.generateRandomPointWithinPolygon)(polygon) : (0, utils_js_1.generateRandomPointOnPolygonPerimeter)(polygon);
17
- return res ? { position: res } : null;
19
+ return Promise.resolve(res ? { position: res } : null);
18
20
  }
19
21
  resize(position, size) {
20
22
  super.resize(position, size);
21
- this.polygon = (0, utils_js_1.generateRandomPolygon)(position, this.sides, size.width / 2, this.angle);
23
+ this.polygon = (0, utils_js_1.generateRandomPolygon)(position, this.sides, size.width * half, this.angle);
22
24
  }
23
25
  }
24
26
  exports.EmittersPolygonShape = EmittersPolygonShape;
package/cjs/index.js CHANGED
@@ -4,8 +4,7 @@ exports.loadEmittersShapePolygon = void 0;
4
4
  const EmittersPolygonShapeGenerator_js_1 = require("./EmittersPolygonShapeGenerator.js");
5
5
  async function loadEmittersShapePolygon(engine, refresh = true) {
6
6
  const emittersEngine = engine;
7
- emittersEngine.addEmitterShapeGenerator &&
8
- emittersEngine.addEmitterShapeGenerator("polygon", new EmittersPolygonShapeGenerator_js_1.EmittersPolygonShapeGenerator());
7
+ emittersEngine.addEmitterShapeGenerator?.("polygon", new EmittersPolygonShapeGenerator_js_1.EmittersPolygonShapeGenerator());
9
8
  await emittersEngine.refresh(refresh);
10
9
  }
11
10
  exports.loadEmittersShapePolygon = loadEmittersShapePolygon;
package/cjs/utils.js CHANGED
@@ -2,8 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isPointInPolygon = exports.generateRandomPointOnPolygonPerimeter = exports.generateRandomPointWithinPolygon = exports.generateRandomPolygon = void 0;
4
4
  const engine_1 = require("@tsparticles/engine");
5
- function generateRandomPolygon(position, sides, radius, rotationAngle = 0) {
6
- const polygon = [], angle = (Math.PI * 2) / sides;
5
+ const double = 2, doublePI = Math.PI * double, defaultRotation = 0, maxAttempts = 100;
6
+ function generateRandomPolygon(position, sides, radius, rotationAngle = defaultRotation) {
7
+ const polygon = [], angle = doublePI / sides;
7
8
  for (let i = 0; i < sides; i++) {
8
9
  const currentAngle = angle * i + rotationAngle;
9
10
  polygon.push({
@@ -15,7 +16,7 @@ function generateRandomPolygon(position, sides, radius, rotationAngle = 0) {
15
16
  }
16
17
  exports.generateRandomPolygon = generateRandomPolygon;
17
18
  function generateRandomPointWithinPolygon(polygon) {
18
- const min = { ...polygon[0] }, max = { ...polygon[0] };
19
+ const firstIndex = 0, firstPoint = polygon[firstIndex], min = { ...firstPoint }, max = { ...firstPoint };
19
20
  for (const point of polygon) {
20
21
  if (point.x < min.x) {
21
22
  min.x = point.x;
@@ -31,7 +32,7 @@ function generateRandomPointWithinPolygon(polygon) {
31
32
  }
32
33
  }
33
34
  let randomPoint = null;
34
- for (let attempts = 0; attempts < 100; attempts++) {
35
+ for (let attempts = 0; attempts < maxAttempts; attempts++) {
35
36
  const tmpPoint = {
36
37
  x: min.x + (0, engine_1.getRandom)() * (max.x - min.x),
37
38
  y: min.y + (0, engine_1.getRandom)() * (max.y - min.y),
@@ -45,13 +46,14 @@ function generateRandomPointWithinPolygon(polygon) {
45
46
  }
46
47
  exports.generateRandomPointWithinPolygon = generateRandomPointWithinPolygon;
47
48
  function generateRandomPointOnPolygonPerimeter(polygon) {
48
- const sideIndex = Math.floor((0, engine_1.getRandom)() * polygon.length), startPoint = polygon[sideIndex], endPoint = polygon[(sideIndex + 1) % polygon.length], t = (0, engine_1.getRandom)();
49
+ const sideIndex = Math.floor((0, engine_1.getRandom)() * polygon.length), startPoint = polygon[sideIndex], offset = 1, endPoint = polygon[(sideIndex + offset) % polygon.length], t = (0, engine_1.getRandom)();
49
50
  return { x: startPoint.x + (endPoint.x - startPoint.x) * t, y: startPoint.y + (endPoint.y - startPoint.y) * t };
50
51
  }
51
52
  exports.generateRandomPointOnPolygonPerimeter = generateRandomPointOnPolygonPerimeter;
52
53
  function isPointInPolygon(point, polygon) {
53
54
  let inside = false;
54
- for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
55
+ const offset = 1;
56
+ for (let i = 0, j = polygon.length - offset; i < polygon.length; j = i++) {
55
57
  const pi = polygon[i], pj = polygon[j];
56
58
  const intersect = pi.y > point.y !== pj.y > point.y && point.x < ((pj.x - pi.x) * (point.y - pi.y)) / (pj.y - pi.y) + pi.x;
57
59
  if (intersect) {
@@ -1,20 +1,22 @@
1
1
  import { EmitterShapeBase } from "@tsparticles/plugin-emitters";
2
+ import { degToRad } from "@tsparticles/engine";
2
3
  import { generateRandomPointOnPolygonPerimeter, generateRandomPointWithinPolygon, generateRandomPolygon, } from "./utils.js";
4
+ const half = 0.5;
3
5
  export class EmittersPolygonShape extends EmitterShapeBase {
4
6
  constructor(position, size, fill, options) {
5
7
  super(position, size, fill, options);
6
8
  this.sides = options.sides;
7
- this.angle = (options.angle * Math.PI) / 180;
8
- this.polygon = generateRandomPolygon(position, this.sides, size.width / 2, this.angle);
9
+ this.angle = degToRad(options.angle);
10
+ this.polygon = generateRandomPolygon(position, this.sides, size.width * half, this.angle);
9
11
  }
10
12
  async init() {
11
13
  }
12
14
  async randomPosition() {
13
15
  const fill = this.fill, polygon = this.polygon, res = fill ? generateRandomPointWithinPolygon(polygon) : generateRandomPointOnPolygonPerimeter(polygon);
14
- return res ? { position: res } : null;
16
+ return Promise.resolve(res ? { position: res } : null);
15
17
  }
16
18
  resize(position, size) {
17
19
  super.resize(position, size);
18
- this.polygon = generateRandomPolygon(position, this.sides, size.width / 2, this.angle);
20
+ this.polygon = generateRandomPolygon(position, this.sides, size.width * half, this.angle);
19
21
  }
20
22
  }
package/esm/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { EmittersPolygonShapeGenerator } from "./EmittersPolygonShapeGenerator.js";
2
2
  export async function loadEmittersShapePolygon(engine, refresh = true) {
3
3
  const emittersEngine = engine;
4
- emittersEngine.addEmitterShapeGenerator &&
5
- emittersEngine.addEmitterShapeGenerator("polygon", new EmittersPolygonShapeGenerator());
4
+ emittersEngine.addEmitterShapeGenerator?.("polygon", new EmittersPolygonShapeGenerator());
6
5
  await emittersEngine.refresh(refresh);
7
6
  }
package/esm/utils.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { getRandom } from "@tsparticles/engine";
2
- export function generateRandomPolygon(position, sides, radius, rotationAngle = 0) {
3
- const polygon = [], angle = (Math.PI * 2) / sides;
2
+ const double = 2, doublePI = Math.PI * double, defaultRotation = 0, maxAttempts = 100;
3
+ export function generateRandomPolygon(position, sides, radius, rotationAngle = defaultRotation) {
4
+ const polygon = [], angle = doublePI / sides;
4
5
  for (let i = 0; i < sides; i++) {
5
6
  const currentAngle = angle * i + rotationAngle;
6
7
  polygon.push({
@@ -11,7 +12,7 @@ export function generateRandomPolygon(position, sides, radius, rotationAngle = 0
11
12
  return polygon;
12
13
  }
13
14
  export function generateRandomPointWithinPolygon(polygon) {
14
- const min = { ...polygon[0] }, max = { ...polygon[0] };
15
+ const firstIndex = 0, firstPoint = polygon[firstIndex], min = { ...firstPoint }, max = { ...firstPoint };
15
16
  for (const point of polygon) {
16
17
  if (point.x < min.x) {
17
18
  min.x = point.x;
@@ -27,7 +28,7 @@ export function generateRandomPointWithinPolygon(polygon) {
27
28
  }
28
29
  }
29
30
  let randomPoint = null;
30
- for (let attempts = 0; attempts < 100; attempts++) {
31
+ for (let attempts = 0; attempts < maxAttempts; attempts++) {
31
32
  const tmpPoint = {
32
33
  x: min.x + getRandom() * (max.x - min.x),
33
34
  y: min.y + getRandom() * (max.y - min.y),
@@ -40,12 +41,13 @@ export function generateRandomPointWithinPolygon(polygon) {
40
41
  return randomPoint;
41
42
  }
42
43
  export function generateRandomPointOnPolygonPerimeter(polygon) {
43
- const sideIndex = Math.floor(getRandom() * polygon.length), startPoint = polygon[sideIndex], endPoint = polygon[(sideIndex + 1) % polygon.length], t = getRandom();
44
+ const sideIndex = Math.floor(getRandom() * polygon.length), startPoint = polygon[sideIndex], offset = 1, endPoint = polygon[(sideIndex + offset) % polygon.length], t = getRandom();
44
45
  return { x: startPoint.x + (endPoint.x - startPoint.x) * t, y: startPoint.y + (endPoint.y - startPoint.y) * t };
45
46
  }
46
47
  export function isPointInPolygon(point, polygon) {
47
48
  let inside = false;
48
- for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
49
+ const offset = 1;
50
+ for (let i = 0, j = polygon.length - offset; i < polygon.length; j = i++) {
49
51
  const pi = polygon[i], pj = polygon[j];
50
52
  const intersect = pi.y > point.y !== pj.y > point.y && point.x < ((pj.x - pi.x) * (point.y - pi.y)) / (pj.y - pi.y) + pi.x;
51
53
  if (intersect) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/plugin-emitters-shape-polygon",
3
- "version": "3.0.2",
3
+ "version": "3.1.0",
4
4
  "description": "tsParticles emitters shape polygon plugin",
5
5
  "homepage": "https://particles.js.org",
6
6
  "repository": {
@@ -100,8 +100,8 @@
100
100
  "./package.json": "./package.json"
101
101
  },
102
102
  "dependencies": {
103
- "@tsparticles/engine": "^3.0.2",
104
- "@tsparticles/plugin-emitters": "^3.0.2"
103
+ "@tsparticles/engine": "^3.1.0",
104
+ "@tsparticles/plugin-emitters": "^3.1.0"
105
105
  },
106
106
  "publishConfig": {
107
107
  "access": "public"
package/report.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8"/>
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
6
- <title>@tsparticles/plugin-emitters-shape-polygon [6 Dec 2023 at 17:48]</title>
6
+ <title>@tsparticles/plugin-emitters-shape-polygon [13 Jan 2024 at 23:10]</title>
7
7
  <link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABrVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O1foceMD///+J0/qK1Pr7/v8Xdr/9///W8P4UdL7L7P0Scr2r4Pyj3vwad8D5/f/2/f+55f3E6f34+/2H0/ojfMKpzOd0rNgQcb3F3O/j9f7c8v6g3Pz0/P/w+v/q+P7n9v6T1/uQ1vuE0vqLut/y+v+Z2fvt+f+15Pzv9fuc2/vR7v2V2Pvd6/bg9P7I6/285/2y4/yp3/zp8vk8i8kqgMT7/P31+fyv4vxGkcz6/P6/6P3j7vfS5PNnpNUxhcbO7f7F6v3O4vHK3/DA2u631Ouy0eqXweKJud5wqthfoNMMbLvY8f73+v2dxeR8sNtTmdDx9/zX6PSjyeaCtd1YnNGX2PuQveCGt95Nls42h8dLlM3F4vBtAAAAM3RSTlMAAyOx0/sKBvik8opWGBMOAe3l1snDm2E9LSb06eHcu5JpHbarfHZCN9CBb08zzkdNS0kYaptYAAAFV0lEQVRYw92X51/aYBDHHS2O2qqttVbrqNq9m+TJIAYIShBkWwqIiCgoWvfeq7Z2/s29hyQNyUcR7LveGwVyXy6XH8/9rqxglLfUPLxVduUor3h0rfp2TYvpivk37929TkG037hffoX0+peVtZQc1589rigVUdXS/ABSAyEmGIO/1XfvldSK8vs3OqB6u3m0nxmIrvgB0dj7rr7Y9IbuF68hnfFaiHA/sxqm0wciIG43P60qKv9WXWc1RXGh/mFESFABTSBi0sNAKzqet17eCtOb3kZIDwxEEU0oAIJGYxNBDhBND29e0rtXXbcpuPmED9IhEAAQ/AXEaF8EPmnrrKsv0LvWR3fg5sWDNAFZOgAgaKvZDogHNU9MFwnnYROkc56RD5CjAbQX9Ow4g7upCsvYu55aSI/Nj0H1akgKQEUM94dwK65hYRmFU9MIcH/fqJYOZYcnuJSU/waKDgTOEVaVKhwrTRP5XzgSpAITYzom7UvkhFX5VutmxeNnWDjjswTKTyfgluNDGbUpWissXhF3s7mlSml+czWkg3D0l1nNjGNjz3myOQOa1KM/jOS6ebdbAVTCi4gljHSFrviza7tOgRWcS0MOUX9zdNgag5w7rRqA44Lzw0hr1WqES36dFliSJFlh2rXIae3FFcDDgKdxrUIDePr8jGcSClV1u7A9xeN0ModY/pHMxmR1EzRh8TJiwqsHmKW0l4FCEZI+jHio+JdPPE9qwQtTRxku2D8sIeRL2LnxWSllANCQGOIiqVHAz2ye2JR0DcH+HoxDkaADLjgxjKQ+AwCX/g0+DNgdG0ukYCONAe+dbc2IAc6fwt1ARoDSezNHxV2Cmzwv3O6lDMV55edBGwGK9n1+x2F8EDfAGCxug8MhpsMEcTEAWf3rx2vZhe/LAmtIn/6apE6PN0ULKgywD9mmdxbmFl3OvD5AS5fW5zLbv/YHmcsBTjf/afDz3MaZTVCfAP9z6/Bw6ycv8EUBWJIn9zYcoAWWlW9+OzO3vkTy8H+RANLmdrpOuYWdZYEXpo+TlCJrW5EARb7fF+bWdqf3hhyZI1nWJQHgznErZhbjoEsWqi8dQNoE294aldzFurwSABL2XXMf9+H1VQGke9exw5P/AnA5Pv5ngMul7LOvO922iwACu8WkCwLCafvM4CeWPxfA8lNHcWZSoi8EwMAIciKX2Z4SWCMAa3snCZ/G4EA8D6CMLNFsGQhkkz/gQNEBbPCbWsxGUpYVu3z8IyNAknwJkfPMEhLyrdi5RTyUVACkw4GSFRNWJNEW+fgPGwHD8/JxnRuLabN4CGNRkAE23na2+VmEAUmrYymSGjMAYqH84YUIyzgzs3XC7gNgH36Vcc4zKY9o9fgPBXUAiHHwVboBHGLiX6Zcjp1f2wu4tvzZKo0ecPnDtQYDQvJXaBeNzce45Fp28ZQLrEZVuFqgBwOalArKXnW1UzlnSusQKJqKYNuz4tOnI6sZG4zanpemv+7ySU2jbA9h6uhcgpfy6G2PahirDZ6zvq6zDduMVFTKvzw8wgyEdelwY9in3XkEPs3osJuwRQ4qTkfzifndg9Gfc4pdsu82+tTnHZTBa2EAMrqr2t43pguc8tNm7JQVQ2S0ukj2d22dhXYP0/veWtwKrCkNoNimAN5+Xr/oLrxswKbVJjteWrX7eR63o4j9q0GxnaBdWgGA5VStpanIjQmEhV0/nVt5VOFUvix6awJhPcAaTEShgrG+iGyvb5a0Ndb1YGHFPEwoqAinoaykaID1o1pdPNu7XsnCKQ3R+hwWIIhGvORcJUBYXe3Xa3vq/mF/N9V13ugufMkfXn+KHsRD0B8AAAAASUVORK5CYII=" type="image/x-icon" />
8
8
 
9
9
  <script>
@@ -31,7 +31,7 @@
31
31
  <body>
32
32
  <div id="app"></div>
33
33
  <script>
34
- window.chartData = [{"label":"tsparticles.plugin.emitters.shape.polygon.js","isAsset":true,"statSize":4058,"parsedSize":8218,"gzipSize":2399,"groups":[{"label":"dist/browser","path":"./dist/browser","statSize":3974,"groups":[{"id":659,"label":"index.js + 4 modules (concatenated)","path":"./dist/browser/index.js + 4 modules (concatenated)","statSize":3974,"parsedSize":8218,"gzipSize":2399,"concatenated":true,"groups":[{"label":"dist/browser","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser","statSize":3974,"groups":[{"id":null,"label":"index.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/index.js","statSize":366,"parsedSize":756,"gzipSize":220,"inaccurateSizes":true},{"id":null,"label":"EmittersPolygonShapeGenerator.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/EmittersPolygonShapeGenerator.js","statSize":421,"parsedSize":870,"gzipSize":254,"inaccurateSizes":true},{"label":"Options/Classes","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/Options/Classes","statSize":308,"groups":[{"id":null,"label":"EmittersPolygonShapeOptions.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/Options/Classes/EmittersPolygonShapeOptions.js","statSize":308,"parsedSize":636,"gzipSize":185,"inaccurateSizes":true}],"parsedSize":636,"gzipSize":185,"inaccurateSizes":true},{"id":null,"label":"EmittersPolygonShape.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/EmittersPolygonShape.js","statSize":945,"parsedSize":1954,"gzipSize":570,"inaccurateSizes":true},{"id":null,"label":"utils.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/utils.js","statSize":1934,"parsedSize":3999,"gzipSize":1167,"inaccurateSizes":true}],"parsedSize":8218,"gzipSize":2399,"inaccurateSizes":true}]}],"parsedSize":8218,"gzipSize":2399},{"label":"engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","statSize":42,"groups":[{"id":533,"label":"engine\",\"root\":\"window\"}","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles/engine\",\"root\":\"window\"}","statSize":42}],"parsedSize":0,"gzipSize":0},{"label":"plugin-emitters\",\"commonjs2\":\"@tsparticles/plugin-emitters\",\"amd\":\"@tsparticles","path":"./plugin-emitters\",\"commonjs2\":\"@tsparticles/plugin-emitters\",\"amd\":\"@tsparticles","statSize":42,"groups":[{"id":68,"label":"plugin-emitters\",\"root\":\"window\"}","path":"./plugin-emitters\",\"commonjs2\":\"@tsparticles/plugin-emitters\",\"amd\":\"@tsparticles/plugin-emitters\",\"root\":\"window\"}","statSize":42}],"parsedSize":0,"gzipSize":0}],"isInitialByEntrypoint":{"tsparticles.plugin.emitters.shape.polygon":true}}];
34
+ window.chartData = [{"label":"tsparticles.plugin.emitters.shape.polygon.js","isAsset":true,"statSize":4316,"parsedSize":8465,"gzipSize":2499,"groups":[{"label":"dist/browser","path":"./dist/browser","statSize":4232,"groups":[{"id":351,"label":"index.js + 4 modules (concatenated)","path":"./dist/browser/index.js + 4 modules (concatenated)","statSize":4232,"parsedSize":8465,"gzipSize":2499,"concatenated":true,"groups":[{"label":"dist/browser","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser","statSize":4232,"groups":[{"id":null,"label":"index.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/index.js","statSize":325,"parsedSize":650,"gzipSize":191,"inaccurateSizes":true},{"id":null,"label":"EmittersPolygonShapeGenerator.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/EmittersPolygonShapeGenerator.js","statSize":421,"parsedSize":842,"gzipSize":248,"inaccurateSizes":true},{"label":"Options/Classes","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/Options/Classes","statSize":308,"groups":[{"id":null,"label":"EmittersPolygonShapeOptions.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/Options/Classes/EmittersPolygonShapeOptions.js","statSize":308,"parsedSize":616,"gzipSize":181,"inaccurateSizes":true}],"parsedSize":616,"gzipSize":181,"inaccurateSizes":true},{"id":null,"label":"EmittersPolygonShape.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/EmittersPolygonShape.js","statSize":1028,"parsedSize":2056,"gzipSize":607,"inaccurateSizes":true},{"id":null,"label":"utils.js","path":"./dist/browser/index.js + 4 modules (concatenated)/dist/browser/utils.js","statSize":2150,"parsedSize":4300,"gzipSize":1269,"inaccurateSizes":true}],"parsedSize":8465,"gzipSize":2499,"inaccurateSizes":true}]}],"parsedSize":8465,"gzipSize":2499},{"label":"engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","statSize":42,"groups":[{"id":533,"label":"engine\",\"root\":\"window\"}","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles/engine\",\"root\":\"window\"}","statSize":42}],"parsedSize":0,"gzipSize":0},{"label":"plugin-emitters\",\"commonjs2\":\"@tsparticles/plugin-emitters\",\"amd\":\"@tsparticles","path":"./plugin-emitters\",\"commonjs2\":\"@tsparticles/plugin-emitters\",\"amd\":\"@tsparticles","statSize":42,"groups":[{"id":68,"label":"plugin-emitters\",\"root\":\"window\"}","path":"./plugin-emitters\",\"commonjs2\":\"@tsparticles/plugin-emitters\",\"amd\":\"@tsparticles/plugin-emitters\",\"root\":\"window\"}","statSize":42}],"parsedSize":0,"gzipSize":0}],"isInitialByEntrypoint":{"tsparticles.plugin.emitters.shape.polygon":true}}];
35
35
  window.entrypoints = ["tsparticles.plugin.emitters.shape.polygon","tsparticles.plugin.emitters.shape.polygon.min"];
36
36
  window.defaultSizes = "parsed";
37
37
  </script>
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v3.0.2
7
+ * v3.1.0
8
8
  */
9
9
  (function webpackUniversalModuleDefinition(root, factory) {
10
10
  if(typeof exports === 'object' && typeof module === 'object')
@@ -107,9 +107,13 @@ var plugin_emitters_root_window_ = __webpack_require__(68);
107
107
  var engine_root_window_ = __webpack_require__(533);
108
108
  ;// CONCATENATED MODULE: ./dist/browser/utils.js
109
109
 
110
- function generateRandomPolygon(position, sides, radius, rotationAngle = 0) {
110
+ const utils_double = 2,
111
+ doublePI = Math.PI * utils_double,
112
+ defaultRotation = 0,
113
+ maxAttempts = 100;
114
+ function generateRandomPolygon(position, sides, radius, rotationAngle = defaultRotation) {
111
115
  const polygon = [],
112
- angle = Math.PI * 2 / sides;
116
+ angle = doublePI / sides;
113
117
  for (let i = 0; i < sides; i++) {
114
118
  const currentAngle = angle * i + rotationAngle;
115
119
  polygon.push({
@@ -120,11 +124,13 @@ function generateRandomPolygon(position, sides, radius, rotationAngle = 0) {
120
124
  return polygon;
121
125
  }
122
126
  function generateRandomPointWithinPolygon(polygon) {
123
- const min = {
124
- ...polygon[0]
127
+ const firstIndex = 0,
128
+ firstPoint = polygon[firstIndex],
129
+ min = {
130
+ ...firstPoint
125
131
  },
126
132
  max = {
127
- ...polygon[0]
133
+ ...firstPoint
128
134
  };
129
135
  for (const point of polygon) {
130
136
  if (point.x < min.x) {
@@ -141,7 +147,7 @@ function generateRandomPointWithinPolygon(polygon) {
141
147
  }
142
148
  }
143
149
  let randomPoint = null;
144
- for (let attempts = 0; attempts < 100; attempts++) {
150
+ for (let attempts = 0; attempts < maxAttempts; attempts++) {
145
151
  const tmpPoint = {
146
152
  x: min.x + (0,engine_root_window_.getRandom)() * (max.x - min.x),
147
153
  y: min.y + (0,engine_root_window_.getRandom)() * (max.y - min.y)
@@ -156,7 +162,8 @@ function generateRandomPointWithinPolygon(polygon) {
156
162
  function generateRandomPointOnPolygonPerimeter(polygon) {
157
163
  const sideIndex = Math.floor((0,engine_root_window_.getRandom)() * polygon.length),
158
164
  startPoint = polygon[sideIndex],
159
- endPoint = polygon[(sideIndex + 1) % polygon.length],
165
+ offset = 1,
166
+ endPoint = polygon[(sideIndex + offset) % polygon.length],
160
167
  t = (0,engine_root_window_.getRandom)();
161
168
  return {
162
169
  x: startPoint.x + (endPoint.x - startPoint.x) * t,
@@ -165,7 +172,8 @@ function generateRandomPointOnPolygonPerimeter(polygon) {
165
172
  }
166
173
  function isPointInPolygon(point, polygon) {
167
174
  let inside = false;
168
- for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
175
+ const offset = 1;
176
+ for (let i = 0, j = polygon.length - offset; i < polygon.length; j = i++) {
169
177
  const pi = polygon[i],
170
178
  pj = polygon[j];
171
179
  const intersect = pi.y > point.y !== pj.y > point.y && point.x < (pj.x - pi.x) * (point.y - pi.y) / (pj.y - pi.y) + pi.x;
@@ -178,25 +186,27 @@ function isPointInPolygon(point, polygon) {
178
186
  ;// CONCATENATED MODULE: ./dist/browser/EmittersPolygonShape.js
179
187
 
180
188
 
189
+
190
+ const half = 0.5;
181
191
  class EmittersPolygonShape extends plugin_emitters_root_window_.EmitterShapeBase {
182
192
  constructor(position, size, fill, options) {
183
193
  super(position, size, fill, options);
184
194
  this.sides = options.sides;
185
- this.angle = options.angle * Math.PI / 180;
186
- this.polygon = generateRandomPolygon(position, this.sides, size.width / 2, this.angle);
195
+ this.angle = (0,engine_root_window_.degToRad)(options.angle);
196
+ this.polygon = generateRandomPolygon(position, this.sides, size.width * half, this.angle);
187
197
  }
188
198
  async init() {}
189
199
  async randomPosition() {
190
200
  const fill = this.fill,
191
201
  polygon = this.polygon,
192
202
  res = fill ? generateRandomPointWithinPolygon(polygon) : generateRandomPointOnPolygonPerimeter(polygon);
193
- return res ? {
203
+ return Promise.resolve(res ? {
194
204
  position: res
195
- } : null;
205
+ } : null);
196
206
  }
197
207
  resize(position, size) {
198
208
  super.resize(position, size);
199
- this.polygon = generateRandomPolygon(position, this.sides, size.width / 2, this.angle);
209
+ this.polygon = generateRandomPolygon(position, this.sides, size.width * half, this.angle);
200
210
  }
201
211
  }
202
212
  ;// CONCATENATED MODULE: ./dist/browser/Options/Classes/EmittersPolygonShapeOptions.js
@@ -231,7 +241,7 @@ class EmittersPolygonShapeGenerator {
231
241
 
232
242
  async function loadEmittersShapePolygon(engine, refresh = true) {
233
243
  const emittersEngine = engine;
234
- emittersEngine.addEmitterShapeGenerator && emittersEngine.addEmitterShapeGenerator("polygon", new EmittersPolygonShapeGenerator());
244
+ emittersEngine.addEmitterShapeGenerator?.("polygon", new EmittersPolygonShapeGenerator());
235
245
  await emittersEngine.refresh(refresh);
236
246
  }
237
247
  })();
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see tsparticles.plugin.emitters.shape.polygon.min.js.LICENSE.txt */
2
- !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/plugin-emitters"),require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/plugin-emitters","@tsparticles/engine"],t);else{var n="object"==typeof exports?t(require("@tsparticles/plugin-emitters"),require("@tsparticles/engine")):t(e.window,e.window);for(var o in n)("object"==typeof exports?exports:e)[o]=n[o]}}(this,((e,t)=>(()=>{"use strict";var n={533:e=>{e.exports=t},68:t=>{t.exports=e}},o={};function r(e){var t=o[e];if(void 0!==t)return t.exports;var s=o[e]={exports:{}};return n[e](s,s.exports,r),s.exports}r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var s={};return(()=>{r.r(s),r.d(s,{loadEmittersShapePolygon:()=>y});var e=r(68),t=r(533);function n(e,t,n,o=0){const r=[],s=2*Math.PI/t;for(let i=0;i<t;i++){const t=s*i+o;r.push({x:e.x+n*Math.cos(t),y:e.y+n*Math.sin(t)})}return r}function o(e,t){let n=!1;for(let o=0,r=t.length-1;o<t.length;r=o++){const s=t[o],i=t[r];s.y>e.y!=i.y>e.y&&e.x<(i.x-s.x)*(e.y-s.y)/(i.y-s.y)+s.x&&(n=!n)}return n}class i extends e.EmitterShapeBase{constructor(e,t,o,r){super(e,t,o,r),this.sides=r.sides,this.angle=r.angle*Math.PI/180,this.polygon=n(e,this.sides,t.width/2,this.angle)}async init(){}async randomPosition(){const e=this.fill,n=this.polygon,r=e?function(e){const n={...e[0]},r={...e[0]};for(const t of e)t.x<n.x&&(n.x=t.x),t.x>r.x&&(r.x=t.x),t.y<n.y&&(n.y=t.y),t.y>r.y&&(r.y=t.y);let s=null;for(let i=0;i<100;i++){const i={x:n.x+(0,t.getRandom)()*(r.x-n.x),y:n.y+(0,t.getRandom)()*(r.y-n.y)};if(o(i,e)){s=i;break}}return s}(n):function(e){const n=Math.floor((0,t.getRandom)()*e.length),o=e[n],r=e[(n+1)%e.length],s=(0,t.getRandom)();return{x:o.x+(r.x-o.x)*s,y:o.y+(r.y-o.y)*s}}(n);return r?{position:r}:null}resize(e,t){super.resize(e,t),this.polygon=n(e,this.sides,t.width/2,this.angle)}}class a{constructor(){this.angle=0,this.sides=5}load(e){e&&(void 0!==e.angle&&(this.angle=e.angle),void 0!==e.sides&&(this.sides=e.sides))}}class l{generate(e,t,n,o){const r=new a;return r.load(o),new i(e,t,n,r)}}async function y(e,t=!0){const n=e;n.addEmitterShapeGenerator&&n.addEmitterShapeGenerator("polygon",new l),await n.refresh(t)}})(),s})()));
2
+ !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/plugin-emitters"),require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/plugin-emitters","@tsparticles/engine"],t);else{var o="object"==typeof exports?t(require("@tsparticles/plugin-emitters"),require("@tsparticles/engine")):t(e.window,e.window);for(var n in o)("object"==typeof exports?exports:e)[n]=o[n]}}(this,((e,t)=>(()=>{"use strict";var o={533:e=>{e.exports=t},68:t=>{t.exports=e}},n={};function s(e){var t=n[e];if(void 0!==t)return t.exports;var r=n[e]={exports:{}};return o[e](r,r.exports,s),r.exports}s.d=(e,t)=>{for(var o in t)s.o(t,o)&&!s.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),s.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};return(()=>{s.r(r),s.d(r,{loadEmittersShapePolygon:()=>c});var e=s(68),t=s(533);const o=2*Math.PI;function n(e,t,n,s=0){const r=[],i=o/t;for(let o=0;o<t;o++){const t=i*o+s;r.push({x:e.x+n*Math.cos(t),y:e.y+n*Math.sin(t)})}return r}function i(e,t){let o=!1;for(let n=0,s=t.length-1;n<t.length;s=n++){const r=t[n],i=t[s];r.y>e.y!=i.y>e.y&&e.x<(i.x-r.x)*(e.y-r.y)/(i.y-r.y)+r.x&&(o=!o)}return o}class a extends e.EmitterShapeBase{constructor(e,o,s,r){super(e,o,s,r),this.sides=r.sides,this.angle=(0,t.degToRad)(r.angle),this.polygon=n(e,this.sides,.5*o.width,this.angle)}async init(){}async randomPosition(){const e=this.fill,o=this.polygon,n=e?function(e){const o=e[0],n={...o},s={...o};for(const t of e)t.x<n.x&&(n.x=t.x),t.x>s.x&&(s.x=t.x),t.y<n.y&&(n.y=t.y),t.y>s.y&&(s.y=t.y);let r=null;for(let o=0;o<100;o++){const o={x:n.x+(0,t.getRandom)()*(s.x-n.x),y:n.y+(0,t.getRandom)()*(s.y-n.y)};if(i(o,e)){r=o;break}}return r}(o):function(e){const o=Math.floor((0,t.getRandom)()*e.length),n=e[o],s=e[(o+1)%e.length],r=(0,t.getRandom)();return{x:n.x+(s.x-n.x)*r,y:n.y+(s.y-n.y)*r}}(o);return Promise.resolve(n?{position:n}:null)}resize(e,t){super.resize(e,t),this.polygon=n(e,this.sides,.5*t.width,this.angle)}}class l{constructor(){this.angle=0,this.sides=5}load(e){e&&(void 0!==e.angle&&(this.angle=e.angle),void 0!==e.sides&&(this.sides=e.sides))}}class y{generate(e,t,o,n){const s=new l;return s.load(n),new a(e,t,o,s)}}async function c(e,t=!0){const o=e;o.addEmitterShapeGenerator?.("polygon",new y),await o.refresh(t)}})(),r})()));
@@ -1 +1 @@
1
- /*! tsParticles Emitters Shape Polygon Plugin v3.0.2 by Matteo Bruni */
1
+ /*! tsParticles Emitters Shape Polygon Plugin v3.1.0 by Matteo Bruni */
@@ -4,30 +4,32 @@
4
4
  if (v !== undefined) module.exports = v;
5
5
  }
6
6
  else if (typeof define === "function" && define.amd) {
7
- define(["require", "exports", "@tsparticles/plugin-emitters", "./utils.js"], factory);
7
+ define(["require", "exports", "@tsparticles/plugin-emitters", "@tsparticles/engine", "./utils.js"], factory);
8
8
  }
9
9
  })(function (require, exports) {
10
10
  "use strict";
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.EmittersPolygonShape = void 0;
13
13
  const plugin_emitters_1 = require("@tsparticles/plugin-emitters");
14
+ const engine_1 = require("@tsparticles/engine");
14
15
  const utils_js_1 = require("./utils.js");
16
+ const half = 0.5;
15
17
  class EmittersPolygonShape extends plugin_emitters_1.EmitterShapeBase {
16
18
  constructor(position, size, fill, options) {
17
19
  super(position, size, fill, options);
18
20
  this.sides = options.sides;
19
- this.angle = (options.angle * Math.PI) / 180;
20
- this.polygon = (0, utils_js_1.generateRandomPolygon)(position, this.sides, size.width / 2, this.angle);
21
+ this.angle = (0, engine_1.degToRad)(options.angle);
22
+ this.polygon = (0, utils_js_1.generateRandomPolygon)(position, this.sides, size.width * half, this.angle);
21
23
  }
22
24
  async init() {
23
25
  }
24
26
  async randomPosition() {
25
27
  const fill = this.fill, polygon = this.polygon, res = fill ? (0, utils_js_1.generateRandomPointWithinPolygon)(polygon) : (0, utils_js_1.generateRandomPointOnPolygonPerimeter)(polygon);
26
- return res ? { position: res } : null;
28
+ return Promise.resolve(res ? { position: res } : null);
27
29
  }
28
30
  resize(position, size) {
29
31
  super.resize(position, size);
30
- this.polygon = (0, utils_js_1.generateRandomPolygon)(position, this.sides, size.width / 2, this.angle);
32
+ this.polygon = (0, utils_js_1.generateRandomPolygon)(position, this.sides, size.width * half, this.angle);
31
33
  }
32
34
  }
33
35
  exports.EmittersPolygonShape = EmittersPolygonShape;
package/umd/index.js CHANGED
@@ -13,8 +13,7 @@
13
13
  const EmittersPolygonShapeGenerator_js_1 = require("./EmittersPolygonShapeGenerator.js");
14
14
  async function loadEmittersShapePolygon(engine, refresh = true) {
15
15
  const emittersEngine = engine;
16
- emittersEngine.addEmitterShapeGenerator &&
17
- emittersEngine.addEmitterShapeGenerator("polygon", new EmittersPolygonShapeGenerator_js_1.EmittersPolygonShapeGenerator());
16
+ emittersEngine.addEmitterShapeGenerator?.("polygon", new EmittersPolygonShapeGenerator_js_1.EmittersPolygonShapeGenerator());
18
17
  await emittersEngine.refresh(refresh);
19
18
  }
20
19
  exports.loadEmittersShapePolygon = loadEmittersShapePolygon;
package/umd/utils.js CHANGED
@@ -11,8 +11,9 @@
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.isPointInPolygon = exports.generateRandomPointOnPolygonPerimeter = exports.generateRandomPointWithinPolygon = exports.generateRandomPolygon = void 0;
13
13
  const engine_1 = require("@tsparticles/engine");
14
- function generateRandomPolygon(position, sides, radius, rotationAngle = 0) {
15
- const polygon = [], angle = (Math.PI * 2) / sides;
14
+ const double = 2, doublePI = Math.PI * double, defaultRotation = 0, maxAttempts = 100;
15
+ function generateRandomPolygon(position, sides, radius, rotationAngle = defaultRotation) {
16
+ const polygon = [], angle = doublePI / sides;
16
17
  for (let i = 0; i < sides; i++) {
17
18
  const currentAngle = angle * i + rotationAngle;
18
19
  polygon.push({
@@ -24,7 +25,7 @@
24
25
  }
25
26
  exports.generateRandomPolygon = generateRandomPolygon;
26
27
  function generateRandomPointWithinPolygon(polygon) {
27
- const min = { ...polygon[0] }, max = { ...polygon[0] };
28
+ const firstIndex = 0, firstPoint = polygon[firstIndex], min = { ...firstPoint }, max = { ...firstPoint };
28
29
  for (const point of polygon) {
29
30
  if (point.x < min.x) {
30
31
  min.x = point.x;
@@ -40,7 +41,7 @@
40
41
  }
41
42
  }
42
43
  let randomPoint = null;
43
- for (let attempts = 0; attempts < 100; attempts++) {
44
+ for (let attempts = 0; attempts < maxAttempts; attempts++) {
44
45
  const tmpPoint = {
45
46
  x: min.x + (0, engine_1.getRandom)() * (max.x - min.x),
46
47
  y: min.y + (0, engine_1.getRandom)() * (max.y - min.y),
@@ -54,13 +55,14 @@
54
55
  }
55
56
  exports.generateRandomPointWithinPolygon = generateRandomPointWithinPolygon;
56
57
  function generateRandomPointOnPolygonPerimeter(polygon) {
57
- const sideIndex = Math.floor((0, engine_1.getRandom)() * polygon.length), startPoint = polygon[sideIndex], endPoint = polygon[(sideIndex + 1) % polygon.length], t = (0, engine_1.getRandom)();
58
+ const sideIndex = Math.floor((0, engine_1.getRandom)() * polygon.length), startPoint = polygon[sideIndex], offset = 1, endPoint = polygon[(sideIndex + offset) % polygon.length], t = (0, engine_1.getRandom)();
58
59
  return { x: startPoint.x + (endPoint.x - startPoint.x) * t, y: startPoint.y + (endPoint.y - startPoint.y) * t };
59
60
  }
60
61
  exports.generateRandomPointOnPolygonPerimeter = generateRandomPointOnPolygonPerimeter;
61
62
  function isPointInPolygon(point, polygon) {
62
63
  let inside = false;
63
- for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
64
+ const offset = 1;
65
+ for (let i = 0, j = polygon.length - offset; i < polygon.length; j = i++) {
64
66
  const pi = polygon[i], pj = polygon[j];
65
67
  const intersect = pi.y > point.y !== pj.y > point.y && point.x < ((pj.x - pi.x) * (point.y - pi.y)) / (pj.y - pi.y) + pi.x;
66
68
  if (intersect) {