Open tg8 opened 9 years ago
Same here. The code fails for certain choices of sites, for apparently no good reason.
The problem cannot always be fixed by making the bbox bigger.
Here is another example. One cell cannot be closed because it has one extra nonsensical edge.
<!DOCTYPE html>
<html>
<head>
<script
src="https://code.jquery.com/jquery-1.12.4.js"
integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU="
crossorigin="anonymous">
</script>
</head>
<body id='main_node'>
<script src="Javascript-Voronoi/rhill-voronoi-core.min.js"></script>
<script>
dpts = [[0.20001000000000002,1],[0.80001,0.9],[0.10001,0.1],[0.6000099999999999,0.1],[0.8,1],[0.6000099999999999,0.9],[1.00001,0.1],[0.90001,0.1],[0.20001000000000002,0.8],[0.9,0.10001],[0.599995,0.10000866025403785],[0.10001,0.4],[0.80001,0.4],[0.10001,0],[0.6000099999999999,0.2],[0.199995,0.8000086602540379],[0.40001000000000003,1],[0.4,0.8],[0.90001,0.4],[0.59999,0.2],[0.9,0.2],[0.90001,0],[0.90001,0.8],[0.80001,0.2],[1,0.8],[0.2,0.6],[0.999995,0.10000866025403785],[0.099995,0.10000866025403785],[0.8999900000000001,1.2246467991473532e-21],[0.7999900000000001,0.9],[0.8999900000000001,0.8],[0.9,1],[0.7999900000000001,0.2],[0.09999000000000001,0.4],[0.59999,0.9],[0.6,0.8],[0.4,0.1],[0.8999900000000001,0.1],[0.2,0.1],[1,0.2],[0.7999900000000001,0.4],[0.6,0.6],[0.40001000000000003,0.4],[0.1,0.8],[0.10001,0.2],[0.09999000000000001,0.2],[0.099995,0.09999133974596217],[0.09999000000000001,1.2246467991473532e-21],[0.80001,0.8],[0.599995,0.09999133974596217],[0.19999,1],[0.39999,0.4],[0.7999900000000001,0.8],[0.199995,0.7999913397459621],[0.90001,0.6],[0.8999900000000001,0.6],[1,0],[0.8,0.1],[0.9,0.09999000000000001],[0.6,0.4],[0.999995,0.09999133974596217],[0.1,0.6],[0,0.6],[0.8999900000000001,0.4],[0.39999,1]]
var voronoi = new Voronoi();
//dpts = dpts.slice(0);
//spread_identical_points(dpts);
xs = [];
ys = [];
dpts.forEach( function(dpt) { xs.push(dpt[0]); ys.push(dpt[1]); } );
var eps = 1e-2;
var bbox = {xl: Math.min.apply(null, xs)-eps, xr: Math.max.apply(null, xs)+eps, yt: Math.min.apply(null, ys)-eps, yb: Math.max.apply(null, ys)+eps};
// xl is x-left, xr is x-right, yt is y-top, and yb is y-bottom
//var bbox = {xl:-1000, xr: 1000, yt: -1000, yb: 1000};
var sites = [];
dpts.forEach(function (el) { sites.push({x: el[0], y: el[1]} ); });
// a 'vertex' is an object exhibiting 'x' and 'y' properties. The
// Voronoi object will add a unique 'voronoiId' property to all
// sites. The 'voronoiId' can be used as a key to lookup the associated cell
// in diagram.cells.
try {
var diagram = voronoi.compute(sites, bbox);
}
catch (err) {
function scale_and_shift(x) { return x*1000+100; }
var html = "<svg height=\"1200\" width=\"1200\">";
voronoi.edges.forEach(function(edge){
x1 = scale_and_shift(edge.va.x);
y1 = scale_and_shift(edge.va.y);
x2 = scale_and_shift(edge.vb.x);
y2 = scale_and_shift(edge.vb.y);
html+=" <line x1=\""+x1+"\" y1=\""+y1+"\" x2=\""+x2+"\" y2=\""+y2+"\" style=\"stroke:rgb(0,0,0);stroke-width:2\" />";
});
voronoi.cells.forEach(function(cell){
x = scale_and_shift(cell.site.x);
y = scale_and_shift(cell.site.y);
html+=" <circle cx=\""+x+"\" cy=\""+y+"\" r=\"10\" stroke-width=\"0\" fill=\""+((cell.closeMe)?"red":"#0000FF88")+"\" />;";
if (cell.closeMe) {
cell.halfedges.forEach(function(halfedge){
x1 = scale_and_shift(halfedge.edge.va.x);
y1 = scale_and_shift(halfedge.edge.va.y);
x2 = scale_and_shift(halfedge.edge.vb.x);
y2 = scale_and_shift(halfedge.edge.vb.y);
html+=" <line x1=\""+x1+"\" y1=\""+y1+"\" x2=\""+x2+"\" y2=\""+y2+"\" style=\"stroke:#FF0000;stroke-width:4\" />";
});
voronoi.edges.forEach(function(edge, index){ if (edge===cell.halfedges[1].edge) console.log("edge index:",index);});
}
});
html+="</svg>";
$("body").append(html);
}
</script>
</body>
</html>
@tg8 , I know this ticket is quite old, but as it's still open, I'm documenting the solution as I think this is actually a fix that can allow it to be closed.
equalWithEpsilon, greaterThanWithEpsilon, ...
Now this "ε" is actually only relative to the resolution of the numbers we feed in as input.
The numbers you provided are extremely big in comparison with the numbers usually used for testing and taken as examples to configure the "ε" value to 1e-9Long story short, but first before getting to the solution, I went through a replacement of all "1e-9" instances in the code with the constantVoronoi.ε, although I think that replacement within the comparison functions might have been enough, yet would not be consistent enough.
So in one sentence, richer numbers, are subject to bigger errors and needs wider comparison margin => bigger "ε"
Changing the following lines (after replacement) do fix the issue : file : rhill-voronoi-core.js ~ line 125
//Voronoi.prototype.ε = Voronoi.ε = 1e-9;//crash
//Voronoi.prototype.ε = Voronoi.ε = 1e-8;//crash
Voronoi.prototype.ε = Voronoi.ε = 1e-7;//no crash
Voronoi.prototype.invε = Voronoi.invε = 1.0 / Voronoi.ε;
Voronoi.prototype.equalWithEpsilon = function(a,b){return this.abs(a-b)<Voronoi.ε;};
Voronoi.prototype.greaterThanWithEpsilon = function(a,b){return (a-b)>Voronoi.ε;};
Voronoi.prototype.greaterThanOrEqualWithEpsilon = function(a,b){return (b-a)<Voronoi.ε;};
Voronoi.prototype.lessThanWithEpsilon = function(a,b){return (b-a)>Voronoi.ε;};
Voronoi.prototype.lessThanOrEqualWithEpsilon = function(a,b){return (a-b)<Voronoi.ε;};
The following parameters cause "this makes no sense!" exception:
When
yb:2000000
line is uncommented - exception goes away. If I put some visualizing code just in front ofthis.closeCells(bbox);
call, I get the following picture: where in green arethis.edges
state just before the call. Exception happens when the cell for the "B" site is processed. I'm usingrhill-voronoi-core.js
from the current master branch. Complete example https://gist.github.com/tg8/4b4b2b5c853fbb41f7e1