From 785e38c1936f524c9f693fe0fa953901943ab7e5 Mon Sep 17 00:00:00 2001 From: Amit Patel Date: Wed, 2 Oct 2024 19:48:38 -0700 Subject: [PATCH] git subrepo pull dual-mesh subrepo: subdir: "dual-mesh" merged: "7dc1d22" upstream: origin: "../../x/2312-dual-mesh" branch: "master" commit: "7dc1d22" git-subrepo: version: "0.4.9" origin: "https://github.com/Homebrew/brew" commit: "3994768349" --- dual-mesh/.gitrepo | 6 ++--- dual-mesh/README.org | 2 +- dual-mesh/dist/create.js | 2 +- dual-mesh/dist/index.d.ts | 12 ++++----- dual-mesh/dist/index.js | 42 +++++++++++++++---------------- dual-mesh/dual-mesh-diagrams.js | 1 + dual-mesh/index.org | 18 +++++++++++--- dual-mesh/pnpm-lock.yaml | 44 +++++++++++++++++++++++++++++++++ dual-mesh/tsconfig.json | 2 +- dual-mesh/yarn.lock | 27 -------------------- 10 files changed, 93 insertions(+), 63 deletions(-) create mode 100644 dual-mesh/pnpm-lock.yaml delete mode 100644 dual-mesh/yarn.lock diff --git a/dual-mesh/.gitrepo b/dual-mesh/.gitrepo index fb1d70e..d1e5674 100644 --- a/dual-mesh/.gitrepo +++ b/dual-mesh/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = ../../x/2312-dual-mesh branch = master - commit = fdb9a63e2bdd9666628529b8d727bbccea430bca - parent = 542e3bb206304a9e9025b5285fae7c7d1665445e + commit = 7dc1d22fed5d4433991140ea43968d95c52018c6 + parent = 754dbda04e43cf56032a32f321e931f0504fe151 method = merge - cmdver = 0.4.6 + cmdver = 0.4.9 diff --git a/dual-mesh/README.org b/dual-mesh/README.org index fd19de8..5e507cd 100644 --- a/dual-mesh/README.org +++ b/dual-mesh/README.org @@ -6,7 +6,7 @@ This is a wrapper around [[https://mapbox.github.io/delaunator/][Delaunator]]. I [[https://redblobgames.github.io/dual-mesh/][Documentation is here]], but it's a bit rough. See [[http://www.redblobgames.com/x/1721-voronoi-alternative/][my blog post about centroid polygons]] and [[http://www.redblobgames.com/x/1722-b-rep-triangle-meshes/][my blog post about the dual mesh data structure]] for the history. Those blog posts used the names “seeds, edges, triangles” but now I call them “regions, sides, triangles”, and I use “ghost” elements to eliminate the boundaries. -The naming convention is output-from-input: =x_name_y= takes type =y= (r, s, t) as input and produces type =x= (r, s, t) as output. For example, =r_begin_s= is a function that takes a side (=s=) as input and returns a region (=r=), and could be called ~r = mesh.r_begin_s(s)~. A previous version of this library used the opposite naming convention, input-to-output, but the author was persuaded to switch by [[https://tomforsyth1000.github.io/blog.wiki.html][Tom Forsyth's article on naming]]. +The naming convention is output-from-input: =x_name_y= takes type =y= (r, s, t) as input and produces type =x= (r, s, t) as output. For example, =r_begin_s= is a function that takes a side (=s=) as input and returns a region (=r=), and could be called ~r = mesh.r_begin_s(s)~. A previous version of this library used the opposite naming convention, input-to-output, but the author was persuaded to switch by [[https://tomforsyth1000.github.io/blog.wiki.html#\[\[BMatrix maths and names\]\]][Tom Forsyth's article on naming]]. For efficiency, functions that return an array take an optional parameter where the result should be written: diff --git a/dual-mesh/dist/create.js b/dual-mesh/dist/create.js index 9b66407..eab5d71 100644 --- a/dual-mesh/dist/create.js +++ b/dual-mesh/dist/create.js @@ -24,7 +24,7 @@ let points = generateInteriorBoundaryPoints(bounds, spacing); let numBoundaryPoints = points.length; let generator = new Poisson({ - shape: [bounds.width, bounds.height] + shape: [bounds.width, bounds.height], minDistance: spacing / Math.sqrt(2), }); for (let p of points) { generator.addPoint(p); } diff --git a/dual-mesh/dist/index.d.ts b/dual-mesh/dist/index.d.ts index 4dfcd53..08c3311 100644 --- a/dual-mesh/dist/index.d.ts +++ b/dual-mesh/dist/index.d.ts @@ -96,12 +96,12 @@ export declare class TriangleMesh { s_next_s(s: number): number; s_prev_s(s: number): number; s_opposite_s(s: number): number; - s_around_t(t: number, out_s?: number[]): number[]; - r_around_t(t: number, out_r?: number[]): number[]; - t_around_t(t: number, out_t?: number[]): number[]; - s_around_r(r: number, out_s?: number[]): number[]; - r_around_r(r: number, out_r?: number[]): number[]; - t_around_r(r: number, out_t?: number[]): number[]; + s_around_t(t: number, s_out?: number[]): number[]; + r_around_t(t: number, r_out?: number[]): number[]; + t_around_t(t: number, t_out?: number[]): number[]; + s_around_r(r: number, s_out?: number[]): number[]; + r_around_r(r: number, r_out?: number[]): number[]; + t_around_r(r: number, t_out?: number[]): number[]; r_ghost(): number; is_ghost_s(s: number): boolean; is_ghost_r(r: number): boolean; diff --git a/dual-mesh/dist/index.js b/dual-mesh/dist/index.js index 72ec1b0..2c344cd 100644 --- a/dual-mesh/dist/index.js +++ b/dual-mesh/dist/index.js @@ -181,47 +181,47 @@ export class TriangleMesh { s_next_s(s) { return TriangleMesh.s_next_s(s); } s_prev_s(s) { return TriangleMesh.s_prev_s(s); } s_opposite_s(s) { return this._halfedges[s]; } - s_around_t(t, out_s = []) { out_s.length = 3; for (let i = 0; i < 3; i++) { - out_s[i] = 3 * t + i; - } return out_s; } - r_around_t(t, out_r = []) { out_r.length = 3; for (let i = 0; i < 3; i++) { - out_r[i] = this._triangles[3 * t + i]; - } return out_r; } - t_around_t(t, out_t = []) { out_t.length = 3; for (let i = 0; i < 3; i++) { - out_t[i] = this.t_outer_s(3 * t + i); - } return out_t; } - s_around_r(r, out_s = []) { + s_around_t(t, s_out = []) { s_out.length = 3; for (let i = 0; i < 3; i++) { + s_out[i] = 3 * t + i; + } return s_out; } + r_around_t(t, r_out = []) { r_out.length = 3; for (let i = 0; i < 3; i++) { + r_out[i] = this._triangles[3 * t + i]; + } return r_out; } + t_around_t(t, t_out = []) { t_out.length = 3; for (let i = 0; i < 3; i++) { + t_out[i] = this.t_outer_s(3 * t + i); + } return t_out; } + s_around_r(r, s_out = []) { const s0 = this._s_of_r[r]; let incoming = s0; - out_s.length = 0; + s_out.length = 0; do { - out_s.push(this._halfedges[incoming]); + s_out.push(this._halfedges[incoming]); let outgoing = TriangleMesh.s_next_s(incoming); incoming = this._halfedges[outgoing]; } while (incoming !== -1 && incoming !== s0); - return out_s; + return s_out; } - r_around_r(r, out_r = []) { + r_around_r(r, r_out = []) { const s0 = this._s_of_r[r]; let incoming = s0; - out_r.length = 0; + r_out.length = 0; do { - out_r.push(this.r_begin_s(incoming)); + r_out.push(this.r_begin_s(incoming)); let outgoing = TriangleMesh.s_next_s(incoming); incoming = this._halfedges[outgoing]; } while (incoming !== -1 && incoming !== s0); - return out_r; + return r_out; } - t_around_r(r, out_t = []) { + t_around_r(r, t_out = []) { const s0 = this._s_of_r[r]; let incoming = s0; - out_t.length = 0; + t_out.length = 0; do { - out_t.push(TriangleMesh.t_from_s(incoming)); + t_out.push(TriangleMesh.t_from_s(incoming)); let outgoing = TriangleMesh.s_next_s(incoming); incoming = this._halfedges[outgoing]; } while (incoming !== -1 && incoming !== s0); - return out_t; + return t_out; } r_ghost() { return this.numRegions - 1; } is_ghost_s(s) { return s >= this.numSolidSides; } diff --git a/dual-mesh/dual-mesh-diagrams.js b/dual-mesh/dual-mesh-diagrams.js index 0a83a93..e1da120 100644 --- a/dual-mesh/dual-mesh-diagrams.js +++ b/dual-mesh/dual-mesh-diagrams.js @@ -184,6 +184,7 @@ Vue.component('a-side-white-edges', { `, methods: { w_side: function(s) { + if (this.graph.is_ghost_s(s)) return ``; const alpha = this.alpha || 0.0; let begin = this.graph.pos_of_t(this.graph.t_inner_s(s)); let end = this.graph.pos_of_t(this.graph.t_outer_s(s)); diff --git a/dual-mesh/index.org b/dual-mesh/index.org index a9882e8..b056b6b 100644 --- a/dual-mesh/index.org +++ b/dual-mesh/index.org @@ -180,14 +180,24 @@ But, barely inside means there's a tiny gap between the boundary points and the #+end_export -The accessor functions are named ~output = output_from_input(input)~. Some of them return an array, and will take an optional parameter to reuse an existing array (to avoid memory allocations). +Public data includes: + +- ~numSides, ~numSolidSides~ +- ~numRegions, ~numSolidRegions~ +- ~numTriangles~, ~numSolidTriangles~ +- ~numBoundaryRegions~ + +Static helpers: + +- ~t_from_s(s)~ :: returns the triangle id from a side id +- ~s_next_s(s)~, ~s_prev_s(s)~ :: next/prev around triangle. The black edge =s2= has /next/ edge ={{test('s_next_s',2)}}= and /previous/ edge ={{test('s_prev_s',2)}}=. +The accessor functions are named ~output = output_from_input(input)~. Some of them return an array, and will take an optional parameter to reuse an existing array (to avoid memory allocations). - ~x_of_r(r)~, ~y_of_r(r)~, ~pos_of_r(r, out=[])~ :: the position of region =r= (red point). - ~x_of_t(t)~, ~y_of_t(t)~, ~pos_of_t(t, out=[])~ :: the center position of triangle =t= (blue point). - ~r_begin_s(s)~, ~r_end_s(s)~ :: the black edge endpoints (red). The black edge =s2= /begins/ at ={{test('r_begin_s',2)}}= and /ends/ at ={{test('r_end_s',2)}}=. - ~t_inner_s(s)~, ~t_outer_s(s)~ :: the white edge endpoints (blue). The black edge =s2= has a white edge connecting /inner/ triangle ={{test('t_inner_s',2)}}= to /outer/ triangle ={{test('t_outer_s',2)}}=. -- ~s_next_s(s)~, ~s_prev_s(s)~ :: next/prev around triangle. The black edge =s2= has /next/ edge ={{test('s_next_s',2)}}= and /previous/ edge ={{test('s_prev_s',2)}}=. - ~s_opposite_s(s)~ :: opposite of half-edge. The black edge =s2='s opposite is ={{test('s_opposite_s',2)}}= and =s5='s opposite is ={{test('s_opposite_s',5)}}=. If an edge has no opposite, it will return =-1=. - ~s_around_t(t, out=[])~ :: sides around a triangle. Triangle =t0='s sides are ={{test('s_around_t',0)}}= - ~r_around_t(t, out=[])~ :: regions around a triangle. Triangle =t0='s regions are ={{test('r_around_t',0)}}= @@ -216,6 +226,8 @@ Properties of circulation: - If =s= is returned by ~s_around_r(r)~, then ~r_begin_s(s)~ === =r= - If =s= is returned by ~s_around_t(t)~, then ~t_inner_s(s)~ === =t= +- constructor, ~addGhostStructure()~, ~_update()~ set the internal data structures from Delaunator's data, type =MeshInitializer { points: Point[]; delaunator: Delaunator; numBoundaryPoints?: number; numSolidSides?: number }= + ** History :PROPERTIES: :CUSTOM_ID: history @@ -291,6 +303,6 @@ Feel free to look at [[https://github.com/redblobgames/dual-mesh][@redblobgames/ Created 31 Mar 2023 with the help of Vue.js v2;   - Last modified: 02 May 2023 + Last modified: 24 Jun 2024 #+end_export diff --git a/dual-mesh/pnpm-lock.yaml b/dual-mesh/pnpm-lock.yaml new file mode 100644 index 0000000..7986398 --- /dev/null +++ b/dual-mesh/pnpm-lock.yaml @@ -0,0 +1,44 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + delaunator: + specifier: ^5.0.0 + version: 5.0.1 + poisson-disk-sampling: + specifier: ^2 + version: 2.3.1 + +packages: + + delaunator@5.0.1: + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + + moore@1.0.0: + resolution: {integrity: sha512-xcsFo/jgtMuVaGePHod5TdSzxnRAQQ4wFpDmFuu34lHvx5sNMsioA84NW7iBWYZ10jHR/nyGaDkhunMJxqAzkw==} + + poisson-disk-sampling@2.3.1: + resolution: {integrity: sha512-O3TzHR8IA+Do5zC7EgPdHLOYOpUJ6DikiTwqRqXdSPUhx1ZqfeH6PqAD86KKi+8Nq8vnL2navErsgURKTe089w==} + + robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + +snapshots: + + delaunator@5.0.1: + dependencies: + robust-predicates: 3.0.2 + + moore@1.0.0: {} + + poisson-disk-sampling@2.3.1: + dependencies: + moore: 1.0.0 + + robust-predicates@3.0.2: {} diff --git a/dual-mesh/tsconfig.json b/dual-mesh/tsconfig.json index ee2c457..bd20dd2 100644 --- a/dual-mesh/tsconfig.json +++ b/dual-mesh/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "target": "esnext", - "module": "esnext", + "module": "nodenext", "moduleResolution": "nodenext", "declaration": true, "declarationDir": "dist", diff --git a/dual-mesh/yarn.lock b/dual-mesh/yarn.lock deleted file mode 100644 index 430c475..0000000 --- a/dual-mesh/yarn.lock +++ /dev/null @@ -1,27 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -delaunator@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-5.0.0.tgz#60f052b28bd91c9b4566850ebf7756efe821d81b" - integrity sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw== - dependencies: - robust-predicates "^3.0.0" - -moore@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/moore/-/moore-1.0.0.tgz#1d2b298c32cfd330db0fe81a0b5bac319fd9eb65" - integrity sha1-HSspjDLP0zDbD+gaC1usMZ/Z62U= - -poisson-disk-sampling@^2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/poisson-disk-sampling/-/poisson-disk-sampling-2.2.2.tgz#d326f6be7e1704e1d54e6a024bd44a3fb33120e5" - integrity sha512-N+P2Tydw9leBaTyOwKQv12sgLGkvsZTfa6pHRD8QlbdzFN5gJ0ByzkQrwwKr3W2bxenWgktf9hb4m/RqQ+id4Q== - dependencies: - moore "~1.0.0" - -robust-predicates@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.1.tgz#ecde075044f7f30118682bd9fb3f123109577f9a" - integrity sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==