Clipping non-projection elements (orthographic) - d3.js

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.

Related

Fitting elliptical arcs to points or other curves

I'm struggling to fit an elliptical arc to some points. The points are either from line segments or all part of the same polyline or they are generated from a bezier curve. I basically have two issues:
I would like to fit an elliptical arc to the points if it is reasonable and i straight line if that is a better fit. I'm thinking about starting at the first point and then constructing a line and a ellip_arc to the next points. The one with the lowest error wins. Or something like that at least. The problem is that an ellipse has many free parameters as opposed to a straight line. So how could I fit an ellipse arc to the points? It also has to start and stop at the points.
Fitting seems to be easiest when the ellipse arc is parameterized. Even though I find it hard to define where to start and stop the arc. But, as output, I need to have the ellipse described like in SVG format (Center Point, Minor and Major Axis, rotation to x-axis etc. https://www.w3.org/TR/SVG2/paths.html#PathDataEllipticalArcCommands). I'm not sure how to convert to this representation, or maybe I can fit it like that?
see:
Circular approximation of polygon (or its part)
If you compute this for your curve samples from local change of radius and center you could group and estimate parts of curve that belongs to the same ellipse and also its eccentricity and or a,b semiaxises sizes , center and orientation to ease up your fitting... Even if not get the precise value it will be a start point and range for ellipse parameter fitting hugely improving speed and stability of fitting
Some of the ellipse parameters might be obtained directly if your data has enough large chunks of ellipses see:
Algorithms: Ellipse matching
Fitting SVG like parameters fully will be very slow easier would be to fit just the ellipses first (center,a,b,rotation) and then convert/fit to SVG form elliptic arc. See:
Converting an svg arc to lines
Express SVG arc as series of curves
And finally you can use any fitting algorithm my favorite is this one:
approximation search
I do not code in C# so I have no idea about any existing packages for tasks like this.

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.

Fitting a mesh and a drawing together

Suppose you're trying to render a user's freehand drawings using a 2D triangular mesh. Start with a plain regular mesh of triangles and color their edges to match the drawing as closely as possible. To improve the results, you can move the vertices of the mesh slightly, but keep them within a certain distance of where they would be in a regular mesh so the mesh doesn't become a mess. Let's say that 1/4 of the length of an edge is a fair distance, giving the vertices room to move while keeping them out of each other's personal space.
Here is a hand-made representation of roughly what we're trying to do. Since the drawing is coming freehand from the user, it's a series of line segments taken from mouse movements.
The regular mesh is slightly distorted to allow the user's drawing to be better represented by the edges of the mesh. Unfortunately the end result looks quite bad, but perhaps we could have somehow distorted the drawing to better fit the mesh, and the combination of the two distortions would have created something far more recognizable as the original drawing.
The important thing is to preserve angles, so if the user draws a 90-degree corner it ends up looking close to a 90-degree corner, and if the user draws a straight line it doesn't end up looking like a zigzag. Aside from that, there's no reason why we shouldn't change the drawing in other ways, like translating it, scaling it and so on, because we don't need to exactly preserve distances.
One tricky test case is a perfectly vertical line. The triangular mesh in the image above can easily handle horizontal lines, but a naive approach would turn a vertical line into a jagged mess. The best technique seems to be to horizontally translate the line until it passes through each horizontal edge alternating between 1/4 and 3/4 of the way along the edge. That way we can nudge the vertices to the left or right by 1/4 and get a perfect vertical line. That's obvious to a person, but how can an algorithm be made to see that? It involves moving the line further away from vertices, which is the opposite of what we usually want.
Is there some trick to doing this? Does anyone know of a simple algorithm that gives excellent results?

Tiled Terrain Normals

I am trying to create a terrain solution in ThreeJS and I'm running into some trouble with the generation of the normals. I am approaching the problem by creating a number of mesh objects using the THREE.PlaneGeometry class. Once all of the tiles have been created I go through each and set the UV's so that each tile represents a part of the whole. I also generate a height value of the vertex Y positions to create some hills. I then call the geometry functions
geometry.computeFaceNormals();
geometry.computeVertexNormals();
This is just so that I have some default face and vertex normals for each tile.
I then go through each tile and try to average out the normals on each corner.
The problem is (I think) with the normals, but I don't really know what to call this problem. Each of the normals on the plane's corners point in the same direction as the face when created. This makes the terrain look like a flat shaded object. To prevent this I thought perhaps what I needed to do was make sure each vertext normal (each corner) had the same averaged normal as its immediate neighbours normals. I.E each corner of each tile has the same normal as all the immediate normals around it from the adjacent planes.
figure A
Here I am visualising each of the 4 normals on the mesh. You can see that at each corner the normals are the same (On top of eachother)
figure B
EDIT
figure C
EDIT
Figure D
Except even when the verts all share the same normals it still comes up all blocky <:/
I don't know how to do this... I think my understanding of what needs to be done is incorrect...?
Any help would be greatly appreciated.
You're basically right about what should happen. The shading you're getting is not consistent with continuous normals. If each all the vertex-faces at a given location have the same normal you should not see the clear shading discontinuities in your second image. However the image doesn't look like simple face normals either, at least not to my eye.
A couple of things to look at:
1) I note that your quads themselves are not planar. Is it possible your algorithm is assuming that they are? the non-planar quad meshes don't have real 'face normal' to use as a base.
2) Are your normalized normalized after you average them? That is, do they have a vector length of 1?
3) Are you confident that the normal averaging code is actually using the correct normals to average? The shading in this does not look like completely flat shaded image where each vertex-face normal in a quad is the same - if that were the case you'd get consistent shading across each quad although the quads would not be continuous. This it possible your original vertex-face normals are not in fact lined up with the face normals?
4) Try turning off the bump maps to debug. Depending on how the bump is being done in your shader you may have incorrect binormals/bitangents rather than bad vert normals.
Instead of averaging at each vertex / corner the neighborhood normals you should average the four normals that each vertex has (4 tiles meet at each vertex).

2D geometry outline shader

I want to create a shader to outline 2D geometry. I'm using OpenGL ES2.0. I don't want to use a convolution filter, as the outline is not dependent on the texture, and it is too slow (I tried rendering the textured geometry to another texture, and then drawing that with the convolution shader). I've also tried doing 2 passes, the first being single colorded overscaled geometry to represent an oultine, and then normal drawing on top, but this results in different thicknesses or unaligned outlines. I've looking into how silhouette's in cel-shading are done but they are all calculated using normals and lights, which I don't use at all.
I'm using Box2D for physics, and have "destructable" objects with multiple fixtures. At any point an object can be broken down (fixtures deleted), and I want to the outline to follow the new outter counter.
I'm doing the drawing with a vertex buffer that matches the vertices of the fixtures, preset texture coordinates, and indices to draw triangles. When a fixture is removed, it's associated indices in the index buffer are set to 0, so no triangles are drawn there anymore.
The following image shows what this looks like for one object when it is fully intact.
The red points are the vertex positions (texturing isn't shown), the black lines are the fixtures, and the blue lines show the seperation of how the triangles are drawn. The gray outline is what I would like the outline to look like in any case.
This image shows the same object with a few fixtures removed.
Is this possible to do this in a vertex shader (or in combination with other simple methods)? Any help would be appreciated.
Thanks :)
Assuming you're able to do something about those awkward points that are slightly inset from the corners (eg, if you numbered the points in English-reading order, with the first being '1', point 6 would be one)...
If a point is interior then if you list all the polygon edges connected to it in clockwise order, each pair of edges in sequence will have a polygon in common. If any two edges don't have a polygon in common then it's an exterior point.
Starting from any exterior point you can then get the whole outline by first walking in any direction and subsequently along any edge that connects to an exterior point you haven't visited yet (or, alternatively, that isn't the edge you walked along just now).
Starting from an existing outline and removing some parts, you can obviously start from either exterior point that used to connect to another but no longer does and just walk from there until you get to the other.
You can't handle this stuff in a shader under ES because you don't get connectivity information.
I think the best you could do in a shader is to expand the geometry by pushing vertices outward along their surface normals. Supposing that your data structure is a list of rectangles, each described by, say, a centre, a width and a height, you could achieve the same thing by drawing each with the same centre but with a small amount added to the width and height.
To be completely general you'd need to store normals at vertices, but also to update them as geometry is removed. So there'd be some pushing of new information from the CPU but it'd be relatively limited.

Resources