d3-geo icon indicating copy to clipboard operation
d3-geo copied to clipboard

Simplify dLambda handling in area calculation

Open ajfriend opened this issue 3 months ago • 2 comments

Hi! I was looking at your code here because I'm currently trying to improve our own spherical area calculations in https://github.com/uber/h3, and this has been a super helpful reference.

If I'm not mistaken, I think you can slightly simplify the calculation you have here. Since sin(-x) = -sin(x) and cos(-x) = cos(x), this change should produce exactly the same output. Or, I'm wrong and I learn something, which will be helpful for our use case :)

ajfriend avatar Nov 11 '25 05:11 ajfriend

Testing various browsers at random I didn't find any case of dissymmetry https://observablehq.com/@fil/sin-x-sin-x

Fil avatar Nov 11 '25 07:11 Fil

Thanks for digging in. I tried 4 of the polygons mentioned in https://github.com/d3/d3/issues/1753, and I'm getting the expected area (or at least the sign) for each of them when using my H3 algorithm in C/Python, so I don't think we're suffering from the same issue. This is super helpful to know about tho, in case the issue does come up---maybe in the h3-js bindings? Although, it sounds like this may no longer be an issue in Chrome either...

If the bug is resolved in Chrome, I wonder if you guys get any performance benefit from dropping the extra computation? But I'll leave that to you, since I was mostly interested in our H3 use case. Thanks again for the help!

For future reference, here were the polygons I tested. Note, I had to correct the winding order in polygon 3 of 4 (from what was given in https://github.com/d3/d3/issues/1753):

{"type": "Polygon", "coordinates": [[[-0.0002, 0.0001], [0.0002, 0.0001], [0.0002, 0.0001], [-0.0002, 0.0001]]]}

{"type": "Polygon", "coordinates": [[[-140.64798666866687, -21.670717244865344], [-140.64798666866687, -21.653352776566706], [-140.64798666866687, -21.670717244865344], [-140.71999382938296, -21.670717244865344], [-140.71999382938296, -21.68808171316398], [-140.64798666866687, -21.70544618146262], [-140.61198308830885, -21.722810649761257], [-140.61198308830885, -21.70544618146262], [-140.61198308830885, -21.68808171316398], [-140.64798666866687, -21.670717244865344]]]}

{"type": "Polygon", "coordinates": [[[-149.14483163316334, -17.81580528256805], [-149.14483163316334, -17.7463474093735], [-149.3248495349535, -17.711618472776223], [-149.3248495349535, -17.555338258088497], [-149.4328602760276, -17.503244853192584], [-149.64888175817583, -17.53797378978986], [-149.6128781778178, -17.7463474093735], [-149.3248495349535, -17.7463474093735], [-149.28884595459547, -17.85053421916531], [-149.14483163316334, -17.81580528256805]]]}

{"type": "Polygon", "coordinates": [[[-146.44456310631065, -16.166180794197572], [-146.37255594559457, -16.200909730794848], [-146.33655236523654, -16.200909730794848], [-146.33655236523654, -16.166180794197572], [-146.37255594559457, -16.131451857600297], [-146.44456310631065, -16.148816325898935], [-146.44456310631065, -16.166180794197572]]]}

And I get the following steradian areas: (0.0, 8.848009160972105e-07, 2.4952932182941583e-05, 1.46328996896355e-06)

ajfriend avatar Nov 23 '25 19:11 ajfriend