SVG Path and morphing - svg

I have a bit of a theoretical questions.
Lets say i have 2 paths in svg. Each with a different number of points. One has 4 Bézier curves and the other 3.
What i want to do is morph one into the other.
Now, i know they have to have the same exact structure and same number of points to do so.
So, the question is, can i add "virtual points" into their paths to get the same structure and number of points, without changing the shape of the objects?
For example, taking one point in one of the paths and just adding the same point after it to increase the number of points. Or creating a Bézier curve in both paths that would actually pretend to be a line instead of a curve. Would that change the object? And if i have points on x=1 y=1 and x=4 y=4, would using this form make Bézier curve a line? (M1 1C1 1 4 4 4 4)

Figured it out. Using control points anywhere on the same line as the coordiantes transforms the Bézier into a line, also if you use the same point as both the control points, start and end coordinate you can make the curve into a point. Adding more of these points into path doesnt change the look of the object, just adds more data into the path.
http://www.petercollingridge.co.uk/book/export/html/560
Down at the cubic curves you can align the points in the described manner to get the desired result

I have a simple to use d3 plugin to animate svg path which supports different number of points, also it animates only the parts of the path which differs from original path, not the whole path.
7kb minified: https://pratyushcrd.github.io/d3-path-morphing/

Related

Create a .stl file from a collection of points

So the software I am using accepts 3D objects in the form of contours or .stl files. The contours I have are along the z-plane(each plane has a unique z). I have had to modify the contours for my experiment and now the contours do not have a unique z for each plane(they are now slightly angled wrt z=0 plane).
The points represent the edges of the 3D object. What would be the best way to take this collection of points and create a .stl file?
I am relatively new to working with python and 3D objects, so any help, pointers or suggestions would be much appreciated.
Edit: I have the simplices and verticies using the Delaunay(), but how do I proceed next?
The co-ordinates of all points are in this text file in the format "x y z".
So after seeking an answer for months and trying to use Meshlab and Blender I finally stumbled across the answer using numpy-stl. Hopeful that it will help others in a similar situation.
Here is the code to generate the .STL file:
from stl import mesh
num_triangles=len(fin_list)
data = np.zeros(num_triangles, dtype=mesh.Mesh.dtype)
for i in range(num_triangles):
#I did not know how to use numpy-arrays in this case. This was the major roadblock
# assign vertex co-ordinates to variables to write into mesh
data["vectors"][i] = np.array([[v1x, v1y, v1z],[v2x, v2y, v2z],[v3x, v3y, v3z]])
m=mesh.Mesh(data)
m.save('filename.stl')
The three vertices that form a triangle in the mesh go in as a vector that define the surface normal. I just collected three such vertices that form a triangle and wrote them into the mesh. Since I had a regular array of points, it was easy to collect the triangles:
for i in range(len(point_list)-1):
plane_a=[]
plane_b=[]
for j in range(len(point_list[i])-1):
tri_a=[]
tri_b=[]
#series a triangles
tri_a.append(point_list[i+1][j])
tri_a.append(point_list[i][j+1])
tri_a.append(point_list[i][j])
#series b triangles
tri_b.append(point_list[i+1][j])
tri_b.append(point_list[i+1][j+1])
tri_b.append(point_list[i][j+1])
#load to plane
plane_a.append(tri_a)
plane_b.append(tri_b)
group_a.append(plane_a)
group_b.append(plane_b)
The rules for choosing triangles for creating a mesh are as follows:
The vertices must be arranged in a counter-clock direction.
Each triangle must share two vertices with adjacent triangles.
The direction normal must point out of the surface.
There were two more rules that I did not follow but it still worked in my case:
1. All coordinates must be positive(In 1st Quadrant only)
2. All triangles must be arranged in an increasing z-order.
Note: There can be two kinds of .STL file formats: Binary and ASCII. numpy-stl writes out in the binary format. More info on STL files can be found here.
Hope this helps!

Get SVG path part (or split path)

Input:
SVG path, may consist of Lines and Curves.
percentage length of this path (say 50% of the path)
Output:
svg path that is part of this path from beginning to a given point at length.
There is a nice method on path getPointAtLength and also getPathSegAtLength so we can get the segment at the given length, but still not clear how to "split" this segment and the path that is needed.
I wonder is there some unified solution for the problem.
As you have discovered, the SVGPathElement has methods to step through the segments of a path. You just need to step through them until you get to the one that you have to subdivide. Just be aware that those APIs are in the middle of changing. So you may need to use a polyfill for some browsers - depending on whether you choose to use the new or the old API
The only path segment type that is at all tricky to subdivide are the quadratic and cubic bezier curves. But those are actually pretty easy also, using De Casteljau's algorithm.
See: Divide bezier curve into two equal halves
That answer explains dividing a cubic bezier. However the quadratic version is very similar.

How to find segments in (circular) point map?

I am currently working on a project that involves measuring distances all around a robot with a laser module, the robot then has to move based on the points that he gets.
I currently have access to 360 points that represent the distance from the center for each of the corresponding angles. (a distance for 0°, a distance for 1°, etc)
Here's an example of what the points look like when displayed on a 2D surface:
Circular representation of the points
What I'd like to be able to do is, rather than feeding the robot all 360 points, to feed it segments containing multiple points. For instance, the bottom part of the image would be a single segment even though the points are not completely aligned.
My question to you is, is there an existing algorithm that would help me achieve what I am trying to do?
(I'm working in python but that shouldn't really be a factor)
Thanks a lot.
Assuming your points are ordered:
For each point, look ahead by two points, if the middle point is less than some distance away from the segment between the two points, then push your endpoint 1 pt further, and check that now both of the middle points are still within some distance of your line segment. Proceed to do this until false, at which point roll back one pt and generate a segment, then set the end of that segment as the start of your next segment. Also, you could consider angles instead of just distances as there are some cases where that would be favorable. Also, if no segment can be made from a certain start point for several attempts, push the start point forward one (as not everything is going to simplify into segments)
Alternately, you could convert to Cartesian points and use the hough voting algorithm to detect lines from the resulting point-cloud.

Breaking a path into 100 pixel lines

I have a path drawn in Illustrator, and I need to break the path into section of 100 px. I can't figure out the logic. A line consist of 2 points x1,y1 and x2, y2. And this is for a straight line. My line may have angles/curve, so what do I need to do, to figure out the distance between 2 pixels.Here is a graphic illustration of my line and the sections, which I need to select/extract:
From the shape above, I need to break it into section of lines(note these are not straight lines).
Try referencing the Bug Algorithm. It's a very simple intuitive approach to path planning. I've uploaded an example written in LabVIEW here, but I know there are plenty of others available.
The Bug Algorithm generates a continuous line; a lot of data points; however you can keep a running average of the general diretion it's heading in and detect sharp changes in angles as an important node in the path. This allows you to segment paths from possibly thousands of data points into just a handful.
There are two aspects in your question:
how do I break a path at some point,
how do I find points spaced by a certain distance.
To answer the first, the type of primitives that define the path matters. Assuming a sequence of Bezier cubics, you will resort to the de Casteljau's algorithm: it allows you to construct the control points that correspond to a desired section of a given Bezier arc, from the original control points. Then, a section of a path will be obtained as a starting section of an initial Bezier, then (possibly) a sequence of whole Bezier arcs, and finally the ending section of a last Bezier arc.
To answer the second, assuming that you need an accurate answer, you will need to resort to numerical integration of the arc length along the path. Refer to this post: https://math.stackexchange.com/a/1171564/65203.
For a simple approximation, you can flatten the curve (approximate it as a polyline) and compute the accumulated segment lengths (or even count the pixels if your curve renderer gives you access to this information).
This process is not trivial.

How to describe fat curve (curved line of variable thickness)?

I know how to describe curved line of constant thickness (with Bezier or similar models).
Are there any common models of curved line with variable thickness?
I am imagining some similar things like in Bezier. For example, each node can contain thickness value and it's weight, so renderer would interpolate thickness along curve.
Is there some implementations and/or descriptions?
UPDATE
More precisely the question is follows.
Suppose we have cubic Bezier segment, controlled by 4 points ABCD
In Bezier, the longer we have vector, say AB, then the longer curve follows AB direction. On the picture above, we have raltively long following.
So, I want thikness behave synchronously with control nodes B and C. If AB and CD is long, then thinkness should follow end nodes thinkness long and change to another thickness fast, like below
and if control vectors are short, then thinkness should smoothly change from one to another, like below
Metafont and its successor MetaPost
support variable thickness in the form of shaped pens.
See also
L.M. Mestetskii, Fat curves and representation of planar figures, Computers & Graphics, 24:1 (2000) 9-21 doi: 10.1016/S0097-8493(99)00133-8
If you want to use a "disc based" approach, you need to draw circles around every control point, then find the points on those circles that represent the "offset" (normal to the tangent, for on-curve points, normal to the tangent of the projection for off-curve points). You then plug those new points into the Bezier functions to get your "offset curve".
Curve offsetting, in your case with variable width, is essentially the trick of finding an outline rather than a single curve. For Bezier curves you can find a full explanation over at http://pomax.github.io/bezierinfo/#offsetting, with the variable width explanation over at http://pomax.github.io/bezierinfo/#offsetting (you're interested in the latter, but you need to understand the basics before you look at the special case =)

Resources