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

Mercator’s automatic clip extent is broken when rotated. #89

Closed
mbostock opened this issue Mar 6, 2017 · 4 comments
Closed

Mercator’s automatic clip extent is broken when rotated. #89

mbostock opened this issue Mar 6, 2017 · 4 comments

Comments

@mbostock
Copy link
Member

mbostock commented Mar 6, 2017

See d3/d3-geo-projection#96.

@Fil
Copy link
Member

Fil commented Mar 10, 2017

@jodibean It's easy to fix the example by using geoEquirectangular instead.

The cause is indeed that Mercator "reclips" after translate() and scale()
https://github.com/d3/d3-geo/blob/master/src/projection/mercator.js#L41
I've tried several variations but it always breaks some tests, so I'm not touching it.

However the example json is also interesting for another reason, not related to projection or clipping.

Its geoArea is computed as ~1143 steradians, or 182 * 2π, and its geoBounds as [-180, -90…180, 90]. Looks like the area is so tiny that when we compute the total surface, numerical instability sends it below 0, meaning each feature covers the whole globe :)

Test: console.log(d3.geoArea(geometry) / 2 / Math.PI);

A lazy fix is to compare the area with -epsilon in (at least) bounds.js and area.js.

But the problem is more the implementation, even with the double precision Adder it's wobbling too much around 0.

@mbostock
Copy link
Member Author

mbostock commented Mar 10, 2017

@Fil One big conceptual problem is that the automatic or implied projection.clipExtent doesn’t make sense when the Mercator projection is rotated—the square bounds of the Mercator projection are no longer axis-aligned in screen space. The simplest solution might be to just disable automatic clipping if a non-zero rotation is specified. (You could reasonably make it work for the 90° degree case, too, the most important of which is transverse Mercator, though…) Alternatively if we implemented Sutherland–Hodgman clipping and then the clip extent doesn’t need to be axis-aligned.

@mbostock mbostock changed the title Rotated Mercator breaks? Mercator’s automatic clip extent is broken when rotated. Mar 10, 2017
@Fil
Copy link
Member

Fil commented Mar 12, 2017

About the geoArea of the test json: on second look it seems that the functions are working ok, but it is the winding order on this polygon that is reversed. I didn't notice it at the beginning, because the polygons displayed correctly. However this is, I think, because the (projected) outer polygon is invisible, thus leaving only the hole to be drawn.

@mbostock
Copy link
Member Author

I am dumb. Rotation is not really an issue—it’s just we are calculating the wrong center of the square due to rotation. Rather than using [0, 0] as the center of the world, we need to know the center post-rotation (which we can do easily using rotation.invert or by computing the center while the rotation is temporarily disabled).

This logic will need to be slightly different for transverse Mercator. The default square clip extent is fine, but intersecting with the automatic clip extent needs to happen on y rather than x for transverse.

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