Drawing parallels on map - d3.js

Example http://bl.ocks.org/mbostock/5731693 shows the equator drawn on an equirectangular map, which then transitions to another projection. On the equirectangular projection, the equator is just a straight line running horizontally.
Funny things happen though if I move the parallel to another latitude, say 20⁰. Instead of drawing a straight line 20⁰ above the equator, D3 draws curved segments approaching the 30⁰ parallel midway from the given control points.
Since I'm just starting with D3, I am a bit at loss at what is happening here.

It looks like each point is connected with a great arc of the sphere they are placed on. Great arcs are defined as sections of great circles, which in turn are circles that divide a sphere in half.
Great arcs are the shortest paths that connect two points on a sphere. They are the equivalent of going in a strait line across the surface of a sphere. On the equator, which is a great circle (since it divides the globe into the north and south hemispheres), these great arcs are part of the equator forming what looks like a straight line on an equirectanglar projection. Since the 20⁰ latitude line is not a great circle, the most direct path between any two points on it will not lie on the line, and will instead be arcs that lie to the north of the 20⁰ latitude line.
For a great circle, you can use the coordinates [[-180, 20], [-90, 0], [0, -20], [90, 0], [180, 20]]

Related

How do I find the corners of a plane in 3d space if I know three points

Apologies in advance for my feeble maths.
I'm trying to be able to find the corners of a plane in space based on the equation of that plane. Here's what I know. I know three points on the plane and I know where they fall in the 2d coordinate space of the plane (x,y) and where they are in 3d space. I know the width and height of the plane and I can now calculate the equation of the plane. The plane sits on the inside of a large sphere that surrounds the origin so, in theory, it should more or less face where the camera is (though in my diagram it doesn't face the origin as it's just for illustrative purposes)
But it's not clear to me how I can use that to figure out another point. One thought I had was to find the transform that moves the plane parallel to the xy axis and rotate it round one of the points (so it stays in the same place), find the position of the new point, and then rotate it by the inverse of that transform. But it's not clear to me how I would find that transform matrix or how to use it. Could I do this using the normal and vector maths? I understand what normals are, but I'm fuzzy about how to use them.

Simulating Light (Point Source) in 2D Room

I am trying to simulate an omnidirectional light source in a 2D room. I would like to set up a room and have "light" propagate from a point source, stopping only when it reaches a wall. The result is shadows will be cast where the light cannot reach. The below picture shows the problem with several point sources
I am implementing this in D3 JS as part of a game based around the art gallery problem.
I am struggling to come up with a data structure suitable for allowing this simulation and animation. I imagine a circle radiates out from the source, splitting into arcs whenever it encounters a wall? Is there a way to do this without simulating lots of individual light beams?
I don't really think d3 will help here, besides drawing the SVG. On the theoretical side, <circle> elements have defined radii, which means that they will curve at the circumference. Arcs will do the same. The art gallery problem deals with polygonal spaces and circles are (arguably) not polygons.
On the practical side, if you are going to use d3, I would instead recommend making <polygon> elements. From your picture, it looks as though each 'light' covers at least one room, and the points of a polygon can match the coordinates of the walls. Where the lights extend out into other rooms, they look to be, from the dotted lines, triangles in most cases. Where the colors overlap, d3 can help because SVG elements are allowed fill properties with alpha components.
d3.select('svg').append('polygon')
.attr('fill', 'rgba(255, 0, 0, 0.5)')
.attr('d', foo);
That will draw a polygon with a semi-transparent red color.
However, d3 won't help you figure out the coordinates of these lights. IMHO you could do this with a search algorithm which starts at a 'light source' and emanates out in a linear fashion checking for walls. When it finds a wall, it takes the coordinates of that 'stop' point and adds it to the path of the polygon. When the polygon draws, the colors will overlap and appear to be light sources.

Clipping non-projection elements (orthographic)

I'd like to add "flying" (3D) arcs to my orthographic projection, as shown here, but with clipping instead of the fade effect. This seems difficult since the arcs are created independently of the projection. (Each arc is defined by three points obtained from the projection--the start, end, and great circle midpoint extended along a line from the center of the canvas--but the arc itself is drawn using "2D" cardinal interpolation on the corresponding points on the svg canvas.)
My first thought was that I might need to do some spherical geometry to get the coordinates where the clipping happens, but now I'm wondering if there's a more straightforward way to accomplish this (I'm new to D3).
This is what my map looks like without clipping:
I'm also very green to d3, but fortunately I'm also fresh from my own search for a decent solution for clipping flight lines in orthographic. The demo you link to is clever in more ways than one:
The arc is drawn from three points interpolated with a Catmull-Rom curve in the projected 2D coordinates that happens to visually approximate a true circular curve in 3D nicely
The line fades with proximity of either of its points to the clipping plane, as you've pointed out
Drawing the spline in the projected, 2D coordinates eliminates any option to split the line before projection and get visual smoothness for cheap, even if d3 had the functionality natively (which I haven't been able to find anyways). That means that interpolation will have to be a lot more manual.
My first thought was that I might need to do some spherical geometry to get the coordinates where the clipping happens, but now I'm wondering if there's a more straightforward way to accomplish this
I eventually settled with what I consider the most obvious option, which unfortunately you're aiming precisely to avoid:
Obtain the coordinates of the clipping point by the cross product of the current globe center with the normal to the great circle plane of the arc. Given your origin and destination Po and Pd respectively and the globe center C, you're looking for C x (Po x Pd) normalized
Interpolate coordinates between your origin and destination using something like d3.geoInterpolate
Project interpolated point at the right scale (read: elevation) above the ground for that fraction of the flight line
Draw one [smoothed] line from the origin to the clipping point along the interpolated points in between, and another from the clipping point to the destination, moving one accordingly to the background. Watch the cases where the whole line is in front or behind the clipping plane.
To figure out where in the flight path you need to splice your clipped point, you will probably need to compare the great angles of your clipping point to one end vs. end-to-end. Note also that performance takes a hit, but you may still be satisfied with the number of flight lines you've drawn in your example.

Point in polygon on Earth globe

I have a list of coordinates (latitude, longitude) that define a polygon. Its edges are created by connecting two points with the arc that is the shortest path between those points.
My problem is to determine whether another point (let's call it U) lays in or out of the polygon. I've been searching web for hours looking for an algorithm that will be complete and won't have any flaws. Here's what I want my algorithm to support and what to accept (in terms of possible weaknesses):
The Earth may be treated as a perfect sphere (from what I've read it results in 0.3% precision loss that I'm fine with).
It must correctly handle polygons that cross International Date Line.
It must correctly handle polygons that span over the North Pole and South Pole.
I've decided to implement the following approach (as a modification of ray casting algorithm that works for 2D scenario).
I want to pick the point S (latitude, longitude) that is outside of the polygon.
For each pair of vertices that define a single edge, I want to calculate the great circle (let's call it G).
I want to calculate the great circle for pair of points S and U.
For each great circle defined in point 2, I want to calculate whether this great circle intersects with G. If so, I'll check if the intersection point lays on the edge of the polygon.
I will count how many intersections there are, and based on that (even/odd) I'll decide if point U is inside/outside of the polygon.
I know how to implement the calculations from points 2 to 5, but I don't have a clue how to pick a starting point S. It's not that obvious as on 2D plane, since I can't just pick a point that is to the left of the leftmost point.
Any ideas on how can I pick this point (S) and if my approach makes sense and is optimal?
Thanks for any input!
If your polygons are local, you can just take the plane tangent to the earth sphere at the point B, and then calculate the projection of the polygon vertices on that plane, so that the problem becomes reduced to a 2D one.
This method introduces a small error as you are approximating the spherical arcs with straight lines in the projection. If your polygons are small it would probably be insignificant, otherwise, you can add intermediate points along the arcs when doing the projection.
You should also take into account the polygons on the antipodes of B, but those could be discarded taking into account the polygons orientation, or checking the distance between B and some polygon vertex.
Finally, if you have to query too many points for that, you may like to pick some fixed projection planes (for instance, those forming an octahedron wrapping the sphere) and precalculate the projection of the polygons on then. You could even create some 2d indexing structure as a quadtree for every one in order to speed up the lookup.
The biggest issue is to define what we mean by 'inside the polygon'.
On a sphere, every polygon (as long as the lines are not intersecting) defines two regions of the sphere. Both regions are equally qualified to be called the inside of the polygon.
Consider a simple, 1-meter on a side, yellow square around the south pole.
You can think of the yellow area to be the inside of the square OR you can think of the square enclosing everything north of each line (the rest of the earth).
So, technically, any point on the sphere 'validly' inside the polygon.
The only way to disambiguate is to select which side of the polygon you want. For example, define the interior to always be the area to the right of each edge.

Convert latitude longitude to x,y point on a rectangle

It seems that there are lots of information both in Google and here, that speak a lot about many different conversions of latitude,longitude.
So what i'm asking is for you to be simple as possible, and try not sending me to other places to seek an answer.
I am trying to put the entire world in to 2D square, where each point represent the distance(in meters) from a point which I choose to define it (0,0),
Can you give me a mathematical algorithm to do so.
You could either use a azimuthal equidistant or two-point equidistant projection.
Of these the azimuthal equidistant is easiest. To do this, just start at your reference point on the world, and put this in the center of your map. Then proceed outward in concentric circles on the map, and for each new circle plot all the points on the world at the appropriate distance and angle.
After doing this, your map should look like a circle, and all of the points will be the correct distance from your center point.

Resources