Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seemingly non-weird ball collection throws an error in d3.packEnclose() #188

Closed
esperanc opened this issue Jan 1, 2022 · 1 comment
Closed

Comments

@esperanc
Copy link

esperanc commented Jan 1, 2022

The following set of balls throws an error:

let weirdBalls = [
  { x: 14.5, y: 48.5, r: 7.585 },
  { x: 9.5, y: 79.5, r: 2.585 },
  { x: 15.5, y: 73.5, r: 8.585 }
] 
d3.packEnclose(weirdBalls)

Note that these do not seem weird in the sense of having centers that are too close or too small/too big radii.
I tracked down the error to function encloseBasis3, which has the following conditional assignment:

const r = -(A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B);

For this particular data set, A == 4.440892098500626e-16, and my proposed solution is to test for a 'small enough' A :

const r = -(Math.abs(A) > 1e-10
      ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A)
      : C / B);

This seems to work in a project which creates quite a few circles, but there is probably a better solution.

@mbostock
Copy link
Member

mbostock commented Apr 2, 2022

Yes, that looks right to me. encloseBasis3 is generating a circle that doesn’t enclose the three circles (red); the fix you propose looks correct (blue).

Screen Shot 2022-04-02 at 5 12 14 PM

And just for completeness, none of the 2-basis will be correct here.

Screen Shot 2022-04-02 at 5 12 31 PM

https://observablehq.com/d/edc883f49ffd755d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants