From d880035d1494e6f27aa2286e30a8b635323c3558 Mon Sep 17 00:00:00 2001 From: William Ngan Date: Sat, 25 Nov 2017 15:51:12 -0800 Subject: [PATCH] Delaunay demo --- demo/create.delaunay.js | 81 ++++++++++++++++++++++++++++++++--------- demo/index.html | 1 + dist/pts.js | 8 ++++ src/Create.ts | 10 +++++ 4 files changed, 82 insertions(+), 18 deletions(-) diff --git a/demo/create.delaunay.js b/demo/create.delaunay.js index 68a24c4e..4f8465a0 100644 --- a/demo/create.delaunay.js +++ b/demo/create.delaunay.js @@ -1,42 +1,87 @@ -window.demoDescription = "Draw shapes based on the size of space. Resize the window and the drawing will update."; +window.demoDescription = "Generate Delaunay and Voronoi tessellations. When 100 points are added, the diagram will animate and display guidelines at pointer position."; (function() { Pts.namespace( this ); - var space = new CanvasSpace("#pt").setup({bgcolor: "#96bfed", resize: true, retina: true}); + var space = new CanvasSpace("#pt").setup({bgcolor: "#123", resize: true, retina: true}); var form = space.getForm(); //// Demo code --- - var de = new Delaunay(); - let dd = []; - let ddd = []; + var de = new Delaunay(); // Delaunay is a Group of Pts + var triangles = []; // store the delaunay triangles + var cells = []; // store the voronoi cells + var lastPt = new Pt(); + + + // A simple function to repel the points if they are too close + let repel = (size) => { + for (let k=0, len=de.length; k { - de = Delaunay.from( Create.distributeRandom( space.innerBound, 200 ) ); - dd = de.delaunay(); - ddd= de.voronoi(); + + // Create 20 random points and generate initial tessellations + de = Create.delaunay( Create.distributeRandom( space.innerBound, 20 ) ); + triangles = de.delaunay(); + cells= de.voronoi(); }, animate: (time, ftime) => { - - let nearIndex = Polygon.nearestPt( de, space.pointer ); - - let neighbors = de.neighbors( nearIndex, true ).map( (n) => n.triangle ); - form.strokeOnly("#f00", 3).polygons( neighbors ); - - form.strokeOnly("#f00", 1).polygons( dd ); - form.fillOnly("#000").points( de, 3 ); + // draw the cells + form.strokeOnly("#fff", 1).polygons( triangles ); + form.fill("#0c9").points( de, 2, "circle" ); + form.strokeOnly("#0fc").polygons( cells ); + + // If more than 100 pts are added, do fancy things + if (de.length >= 100) { + de[de.length-1] = space.pointer; + repel( 50 ); + triangles = de.delaunay(); + cells= de.voronoi(); + + // Guides: Show the neighbor cells of the point nearest to pointer + let nearIndex = Polygon.nearestPt( de, space.pointer ); + de.neighbors( nearIndex, true ).map( (n) => { + form.strokeOnly("rgba(255,255,0, .9)", 3).polygon( n.triangle ); + form.strokeOnly("rgba(255,255,0,.3)", 1).circle( n.circle ); + form.fillOnly("#fe6", 1).point( n.circle[0], 2 ); + }); + } - - form.stroke("#fff").fill("rgba(255,255,0,.2)").polygons( ddd ); }, + action: (type, x, y) => { + + // Add up to 100 points on mouse move + if (type == "move" && de.length < 100) { + let p = new Pt(x,y); + if (lastPt.$subtract(p).magnitudeSq() > 400) { + lastPt = p; + de.push( p ); + triangles = de.delaunay(); + cells= de.voronoi(); + } + } + } + }); //// ---- diff --git a/demo/index.html b/demo/index.html index f01527f2..0d78433a 100644 --- a/demo/index.html +++ b/demo/index.html @@ -129,6 +129,7 @@

Demo

Shaping.linear

Create.gridCells

Create.noisePts

+

Create.delaunay

SVGForm.scope

HTMLForm.scope

diff --git a/dist/pts.js b/dist/pts.js index 7618fdf3..de5a33af 100644 --- a/dist/pts.js +++ b/dist/pts.js @@ -6061,6 +6061,14 @@ class Create { } return g; } + /** + * Create a Delaunay Group. Use the `.delaunay()` and `.voronoi()` functions in the returned group to generate tessellations. + * @param pts a Group or an array of Pts + * @returns an instance of the Delaunay class + */ + static delaunay(pts) { + return Delaunay.from(pts); + } } exports.Create = Create; /** diff --git a/src/Create.ts b/src/Create.ts index 4a914564..495070ff 100644 --- a/src/Create.ts +++ b/src/Create.ts @@ -129,6 +129,16 @@ export class Create { } return g; } + + + /** + * Create a Delaunay Group. Use the `.delaunay()` and `.voronoi()` functions in the returned group to generate tessellations. + * @param pts a Group or an array of Pts + * @returns an instance of the Delaunay class + */ + static delaunay( pts:GroupLike ):Delaunay { + return Delaunay.from( pts ) as Delaunay; + } }