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

Map in a cube #86

Closed
wants to merge 2 commits into from
Closed

Map in a cube #86

wants to merge 2 commits into from

Conversation

espinielli
Copy link

I am trying to add another polyhedral map projection.
I took inspiration from Furuti's Cubic Globes.

I extended render-world accordingly and I get the following "piece of art" ;-)
polyhedralreichard

If I take away the clipping part in render-world I see this other mess:
polyhedralreichard

So things seems to be somewhat in place but maybe clipping needs special treatment...
Any helps?

First attempt to add a new polyhedral map projection, i.e. Reichard map
projection as described by Furuti at
http://www.progonos.com/furuti/MapProj/Normal/ProjPoly/projPoly2.html
@mbostock
Copy link
Member

You will need clipping to an arbitrary spherical polygon (or at least the outline of the unfolded cube). Jason implemented this for his Airocean World reproduction, but alas he did not open-source the implementation so it is not available. (He also has a demonstration of great circle arc intersection.)

@espinielli
Copy link
Author

It looks like the clip to an arbitrary spherical polygon is needed by other (requested) map projections, #67 , #25.
Out of curiosity, what did prevent Jason from contributing it to D3? Was the implementation not generic enough?

I think Jason outlined some issues and possible solutions in Geographic Clipping/Spherical Polygon Challenges.

PS: Speaking of the great circle arc intersection you mentioned, I did write a post to document my search of the "rationale" for the algorithm used by Jason (and exchange some emails w/ him).
By the way, I miss the point about you mentioning "great circle arc intersection" in this thread/PR...

@espinielli
Copy link
Author

Is this code a D3's implementation? It looks like an old implementation...?

@mbostock
Copy link
Member

That code looks like an old version of src/clip/polygon.js. D3 can clip spherical polygons to a great circle or to the antimeridian, but it cannot clip spherical polygons to another spherical polygon. If you want to implement the equivalent of Weiler–Atherton clipping on the sphere then you’re going to need to be able to compute the intersection of geodesics, which is why I mentioned it.

@espinielli
Copy link
Author

From the code of Cahill-Keys (including polyhedron.js from Jason) I got a working Earth in a Cube.

screen shot 2017-01-15 at 10 26 50 pm

It is a D3v3 version but it shows that polyhedron.js contains enough ingredients to make things work.
Again that code was from @jasondavies ...I do not know under which license it can be used/ported to D3v4 or if I should even take it away from my blocks...

@mbostock
Copy link
Member

@espinielli
Copy link
Author

Not possible. The modified D3v3 version from Jason had a d3.geo.pointInPolygon(point, polygon) which is not in D3v4.

@mbostock
Copy link
Member

Isn’t that the polygonContains function? I’d be fine exposing that as d3.geoPolygonContains.

@mbostock
Copy link
Member

mbostock commented Jan 15, 2017

Though that one requires the input coordinates are in radians, and it’d probably be worth generalizing it to d3.geoContains(feature, point), where feature is any GeoJSON feature (with coordinates in degrees).

@espinielli
Copy link
Author

espinielli commented Jan 17, 2017

I tried by just generating a version of d3.geo that exposes polygonContains.
Using all v4 libraries I get a map without proper clipping:

screen shot 2017-01-17 at 12 00 47 pm

So clipping spherical polygons is really needed...

@Fil
Copy link
Member

Fil commented Jan 17, 2017

very cute :)

on geoPolygonContains, see also d3/d3#2662 (comment)

@espinielli
Copy link
Author

@Fil yes I saw it...but wanted to try the simple things first...not sure I am able to follow up on @mbostock's suggestion.
BTW polygonContains takes coordinates in degrees, see the relevant tests.

@mbostock
Copy link
Member

So if an equivalent to d3.geo.pointInPolygon is available as d3.geoContains (or the internal polygonContains), what API is missing to make this work in v4? Or is it that the replacement for pointInPolygon is not working correctly?

@mbostock
Copy link
Member

I have opened a feature request for d3.geoContains, d3/d3-geo#73, since that has come up twice now and seems like an obvious win.

@espinielli
Copy link
Author

espinielli commented Jan 17, 2017

What I noticed is different is the implementation of recurse in polyhedral.js compared to the one in polyhedron.js.

The latter does something with ring... and outline uses it too

@Fil
Copy link
Member

Fil commented Mar 7, 2017

Hey I have put a lot of effort into this and I have to report I'm stuck at about the same point as @espinielli 😿

For fun I chose the third map in the Furuti page. Building the cube and faces is OK, and much simpler now that we have geoContains.
https://gist.github.com/Fil/49fc5cd4c6ba54465e23c2c6544ff1d3

However, I wasn't able to find how to avoid lines going straight from one face to the other (which is utterly disastrous when it's not going through a shared edge).

Here's what it gives with render-world.
f3

I suppose the answer is some kind of polygon clipping to the set of faces, as Enrico demonstrated in his d3v3 version, but it escapes me how to implement it :(

(After all this time I've spent in d3-geo, I must say its code and operation are still sometimes quite difficult to grasp.)

@mbostock
Copy link
Member

mbostock commented Mar 7, 2017

Have you looked at Jason’s implementation of clipping to an arbitrary spherical polygon? It’s in the clip-polygon branch of d3. It’s four years old and the code has since moved to d3-geo, and as you say the code can be difficult to follow, but it might be helpful in understanding what is necessary.

@Fil
Copy link
Member

Fil commented Mar 7, 2017

I've spent a few more hours on this, now I think I'm beginning to understand a few more things, but still no success. The first step would be to expose the old clipPolygon in d3-geo in a way that would allow to use projection.clipPolygon([polygon]).

But all the names have been changed, it's a strange maze.

If I summarize we now have:

  • d3_geo_clip => exposed as clip

  • d3_geo_clipPolygonRejoin => exposed as clipPolygon

  • d3_geo_clipPolygon => unported (hard); it needs d3_geo_clipPolygonSort d3_geo_clipPolygonDistance and more ; would have to be renamed as clipPolygonSet or something

  • projection.clipPolygon => unported (relatively easy)

I've begun some babbling here
https://gist.github.com/Fil/dd1383ddd8669c8c1b97d5ca5dce1035

good night

@mbostock
Copy link
Member

mbostock commented Mar 8, 2017

If it helps, here’s a compare view for those two commits. The main new things are:

v4’s src/clip/polygon.js corresponds to the clip-polygon branch’s src/geo/clip-polygon-rejoin.js. A bunch of stuff was renamed in the great port to ES modules, but you can see that the two still have similar structure.

One confusion is that in v4 the “polygon” refers to what is being clipped, whereas in the clip-polygon branch the “polygon” refers to how the geometry is clipped. That is, in v4 it’s an abstract algorithm for clipping polygons which is used to implement both circle and antimeridian clipping, whereas in clip-polygon it’s an implementation for clipping spherical geometry to an arbitrary spherical polygon.

@mbostock
Copy link
Member

mbostock commented Mar 8, 2017

One of the difficulties in understand this code is moving between the concrete (e.g., src/clip/circle.js) and abstract (e.g., src/clip/index.js) clipping algorithms. I wonder whether things could be simplified, at the cost of some code duplication, by foregoing any generalized abstract clipping algorithm and having separate implementations for different clipping methods (antimeridian, circle, spherical polygon). That is, a more compositional approach rather than trying to subclass an abstract implementation.

@mbostock
Copy link
Member

mbostock commented Mar 8, 2017

Related to the preceding comment, one of the changes Jason made was to require an intersection sorting function be passed to the abstract clipping algorithm: the one in v4 uses a sorting function that only works for circle or antimeridian clipping.

@Fil
Copy link
Member

Fil commented Mar 8, 2017

I've made a block to help visualise the type of polygons we're dealing with.
https://bl.ocks.org/Fil/694ba0d0bc1fc4c24eb257dc210eb01a
capture d ecran 2017-03-08 10 24 03

PS: maybe it would be necessary to open a new issue for this, in d3-geo?

@mbostock
Copy link
Member

mbostock commented Mar 8, 2017

There’s already an issue for clipping to an arbitrary spherical polygon, d3/d3-geo#46. I think that’s the primary blocking feature for more polyhedral projections.

@Fil
Copy link
Member

Fil commented Jul 23, 2017

I've managed to incorporate Jason Davies' old clip-polygon branch into d3v4, and it sort-of works in some cases works.
furuti 3

more later…

@espinielli
Copy link
Author

This opens the flood's gates!

@Fil
Copy link
Member

Fil commented Jul 24, 2017

Pull-request for clip-polygon opened at d3/d3-geo#108.

For this projection and others of the Furuti collection, let's maybe create a family rather than create them one by one?

@Fil Fil mentioned this pull request Aug 5, 2017
@Fil
Copy link
Member

Fil commented Sep 30, 2017

Closing this in favor of #129 — will be solved after d3-geo/clip (d3/d3-geo#115) is merged and published to npm.

@Fil Fil closed this Sep 30, 2017
Fil added a commit that referenced this pull request Oct 1, 2017
Note that d3-geo-polygon is still unstable. When we stream points that belong to the clipping polygon itself, it sometimes bleeds out -- for example on the Waterman projection with a default aspect -- rotate [0,0]).

I have been as conservative as possible: d3-geo-projection works as usual without d3-geo-polygon, and checks that it has projection.preclip (d3-geo > 1.8.1).

Examples and issues at [d3-geo-polygon](https://github.com/d3/d3-geo-polygon)

Solves #129
Solves #124
Solves d3/d3-geo#108
Solves #86
Fil added a commit that referenced this pull request Feb 20, 2018
Note that d3-geo-polygon is still unstable. When we stream points that belong to the clipping polygon itself, it sometimes bleeds out -- for example on the Waterman projection with a default aspect -- rotate [0,0]).

I have been as conservative as possible: d3-geo-projection works as usual without d3-geo-polygon, and checks that it has projection.preclip (d3-geo > 1.8.1).

Examples and issues at [d3-geo-polygon](https://github.com/d3/d3-geo-polygon)

Solves #129
Solves #124
Solves d3/d3-geo#108
Solves #86
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants