Add triangles along path with D3 - d3.js

I am trying to replicate the image below using OpenLayers and D3.js.
I have tried to add triangles along the path using getPointAtLength() and just adding them as SVG elements, but that does not take care of the orientation of the line. To get this working I would need to find the slope and rotate each triangle.
I have also taken a look at this StackOverflow answer:
How to place arrow head triangles on SVG lines?
This looks great but unfortunately it only works for polylines. However, since I am using D3.js together with OpenLayers it seems like I have to use paths and not polylines since I need the d3.geo.path function to transform all features on the map.
As for now it seems like I have the following options:
Add triangles along the path by calculating the slope at every point. Is there an easy way to calculate slope along a path?
Somehow combine D3.js og and OpenLayers and use polylines instead of paths. Is this possible?
Somehow convert my path to a polyline and draw that one instead of the path. Is there a function for doing this?
Are there other options that I can test out?

You could call getPointAtLength at two points separated by a delta. The slope of the two points would be the slope of the path if the delta is small enough.

Related

Element rotation with point-along-path interpolation - not possible on path with arc?

I am working with D3.js in version 3.x.
Following this tutorial, I am trying to move an element, in this case a rectangle, along a path and rotate the element based on its position on the path.
This works perfectly fine for any path, that does not have an arc as part of it. Something like this:
M56.200012207,96.1999969482c-51,295,-52,294,280,184c-286,-273,-243,-261,-35,-204
The angle is calculated "correct" on a path like this, and the element translates along this path in a smooth way.
But as soon as the path contains an arc, the angle gets some strange values at some points of the arc and therefore the rectangle flips / jumps around based on this angle while translating along the path. A path with an arc looks like this for example:
M56.20001220703125,66.19999694824219a174.796117,174.796117,0,1,0,275.99999999996874,-2.000000000042192
My assumption:
As for creating an arc, we only give some values, like startpoint and angle, and the rest of the points needed to draw the arc are computed in some way by svg.
Based on my tries, i saw that some of the computed points are not actually where i would expect them to be.
The function used in the linked example calculates two points, p1 and p2 and calculates the angle for the rotation by using Math.atan2 on p1 and p2.
I know the points are very close together, but to simplify my explanation, i have some distance between them in the image.
In this image, i would expect p1 to have smaller values for x and y than p2.
There are a lot of points in that area between p1 and p2, so the function calculates the required angle for each of these pairs. For most of them, the angle is correct, but not for all of them as can be seen in the following console.log() output:
Notice that for most points, the angle is around 67 degree, which is supposed to be like this on the respective area of the path. But then there randomly is one angle that is 33 degree, which of course causes this flipping / jumping effect.
For "expected angles" the transition looks good and something like this:
For "not expected angles", the transition looks bad and something like this:
If this happens a few times throughout the transition, this produces the flipping / jumping effect.
My question:
Why is this happening? The arc looks fine and all the points seem to be in place based on visually looking at them on screen.
Is there any way to avoid this while still being able to use paths with an arc inside?
Thank you very much for any help.
Edit: Added a jsfiddle to show you the problems discussed here and in the comments: Element rotation with point-along-path interpolation - not possible on path with arc?
There is a bug in current Chrome (57 and 58 as of writing) that affects the return values for getPointAtLength() when operating on arc path commands.
https://bugs.chromium.org/p/chromium/issues/detail?id=719516
For now there seems to be no easy fix other than smoothing the output values yourself. Or avoiding arc commands in your paths.

Drawing polygons using latitude/longitude values in D3

I have a set of polygons where the position of their vertices (corners) are defined as latitude/longitude values.
I want to use D3 to draw these. I don't want anything fancy (like a background containing the world map, etc). The only thing I want to do is to draw the polygons.
I have looked up on Google for a solution, but what I find is things like http://datamaps.github.io or https://github.com/mbostock/d3/wiki/Geo-Paths and they all show a background of the world map or the like which is what I don't want to do.
Suggestions are welcome.
In your particular case, using the geo functionality of D3 seems like overkill -- all you need to do is use the D3 scales to convert the coordinates to screen coordinates, i.e.
var scale = d3.scale.linear().domain([minCoord, maxCoord]).range([minScreen, maxScreen]);
Demo (based on provided fiddle) here.

How are filled paths rendered?

What are the standard algorithms used in vector graphics for rendering filled paths?
I'm not only interested in the process of rendering strokes, I also would like to know how the shapes are filled - how it is determined if given point is inside or outside the path (I believe even specifying the rules of what inside and outside mean is not a straightforward thing).
find outline (perimeter as polygon)
this I think you already have
triangulate (or cut to convex polygons)
there are many approaches like:
clip ear
Delaunay
see Wiki Polygon triangulation
fill convex triangles/polygons
this is easy either use
gfx lib like OpenGL,DirectX,...
api like GDI
rasterize on your own like in how to rasterize convex polygons
style
This stuff is more complicated then it sound like at the first hear. For:
outline width pen,stroke
convert outline to polygon by shifting it out or in. For more info see this
outline style pen,stroke
full,dash dot,dot dot,... for more info see this
filling style brush
like hatching which is most complicated from all. It involves heavy polygon tweaking similar but much harder then outline width. Some styles are simpler some extremly complicated for example for equidistant line fill simple loop + intersection + inside polygon test will do. To test polygon inside you can use hit test

Render a THREE.Line with variable thickness based on distance from camera

I'm trying to render lines (railroads, roads etc) onto a globe. At present, I'm using THREE.LineBasicMaterial and using the linewidth property to control thickness, but it would look much better if the thickness of the line at a given point was inversely proportional to the distance of that point from the camera.
Is such a thing possible (perhaps with a custom shader) or is the only way to construct a tube that follows the same path as the line? (And if so, what would the best approach be?)

Is there a common technique for drawing a "stretchy" line

I'm trying to figure out how to draw an stretchy/elastic line between two points in openGL/Cocos2d on iPhone. Something like this
Where the "band" get's thinner as the line gets longer. iOS uses the same technique I'm aiming for in the Mail.app, pull to refresh.
First of all, is there a name for this kind of thing?
My first thought was to plot a point on the radius of the starting and ending circles based on the angle between to the two, and draw a quadratic bezier curve using the distance/2 as a control point. But I'm not a maths whizz so I'm struggling to figure out how to place the control point which will adjust the thickness of the path.
But a bigger problem is that I need to fill the shape with a colour, and that doesn't seem to be possible with OpenGL bezier curves as far as I can tell since curves don't seem to form part of a shape that can be filled.
So I looked at using a spline created using a point array, but that opens up a whole new world of mathematical pain as I'd have to figure out where all the points along the edge of the path are.
So before I go down that rabbit hole, I'm wondering wether there's something simpler that I'm overlooking, or if anyone can point me towards the most effective technique.
I'm not sure about a "common" technique that people use, other than calculating it mathematically, but this project, SlimeyRefresh, is a good example of how to accomplish this.

Resources