I followed this thread here (unfortunately its very old, ancient I would say):
Perspective transform of SVG paths (four corner distort)
And this thread contains great pdf explaining how calcuations are done (see below).
Question: in the original post author says the approach will work for simple paths but not arcs. Can someone help me understand - would the approach work for Bezier curves? The font used in the example obviously is using curves though...
One can apply affine transformations to the control points of Bezier curve and get transformed Bezier curve.
But perspective transformations are not applicable to "usual" (used in fonts) Bezier curves - they produce rational Bezier curves.
Related
Given two points and a control point, one can easily draw a bezier path between the two points. What I would like to do use a bezier curve to draw a path that with changing width, by a assigning a "weight" to a the points of the curve which will determine its width. For example, if I give weight=0 to the first point of the curve and weight = 1 to the second point of the curve then something like the following path should be generated (the curve in the picture is cubic, but I am working with quadratic bezier curves):
In order to do this I would need to find the control points of the "edge" curves that determine the shape and then fill the shape that is found between the two new curves. However, I am quite unsure on how this can be done. One thing I thought about was to determine the starting and ending points of the new curves by simple drawing perpendicular segments to the line connecting the original control point and the original end points, but this still doesn't solve the problem of finding the new control points for the new curves.
I would use cubics instead of quadratics.
Yes you offset the control points perpendicularly by your weight but not the control points of BEZIER but control points of interpolation cubic (or catmull-rom) and then just convert that into Bezier control points. See related QAs:
How can i produce multi point linear interpolation?
How to create bezier curves for an arc with different start and end tangent slopes
draw outline for some connected lines
However much easier would be to directly render curve using Shaders and (perpendicular) distance. See:
Draw Quadratic Curve on GPU
That way you would not need to offset anything just interpolate the width of your curve ...
Maybe this could help, also there is an example on variable offseting
https://microbians.com/mathcode
I have a list of cubic bezier curves in 3D, such that the curves are connected to each other and closes a cycle.
I am looking for a way to create a surface from the bezier curves. Eventually i want to triangulate the surface and present it in a graphic application.
Is there an algorithm for surfacing a closed path of cubic bezier segments?
It looks like you only know part of the details of the surface (given by the Bezier curves) and you've to extrapolate the surface out of it. As a simple example I'm imagining a bunch of circles in 3D with the center and radius that will be reconstructed into a sphere.
If this is the case you can use level sets. With level sets, you define a bunch of input parameters that defines the force exerted by the external factors on your surface and the 'tension' of the surface.
Crudely put, level sets define the behaviour of surface as they expand(or contract ) over time. As it expands it tries to maintain it's smoothness while meeting other boundary conditions - like 'sticking' to the circles in this case. So if you want a sphere from bunch of circles, the circles will exert a great force, while the surface will also be very tense.
Physbam has an open source implementation of level sets.
CGAL and PCL also provide a host of methods that generate surfaces from things such as points sets and implicit surface. You may be able to adapt one of them for your use.
You can look into the algorithms they use if you want to implement one on your own. I think at least one of them use the Poisson Surface Reconstruction algorithm.
This question already has answers here:
svg: generate 'outline path'
(2 answers)
Closed 5 years ago.
I want to convert a stroked path to a filled object. (Programmatically, in JavaScript.)
The line is just a simple curved line, a sequence of coordinates. I can render this line as a path, and give it a stroke of a certain thickness... but I'm trying to get a filled shape rather than a stroked line, so that I can do further modifications on it, such as warping it, so the resulting 'stroke' might vary in thickness or have custom bits cut out of it (neither of these things are possible with a real SVG stroke, as far as I can tell).
So I'm trying to manually 'thicken' a line into a solid shape. I can't find any function that does this – I've looked through the docs of D3.js and Raphaël, but no luck. Does anyone know of a library/function that would do this?
Or, even better: if someone could explain to me the geometry theory about how I would do this task manually, by taking the list of line coordinates I have and working out a new path that effectively 'strokes' it, that would be amazing. To put it another way, what does the browser do when you tell it to stroke a path – how does it work out what shape the stroke should be?
There has been a similar question recently:
svg: generate 'outline path'
All in all, this is a non-trivial task. As mentioned in my answer to the linked question, PostScript has a command for generating paths that produce basically the same output as a stroke, called strokepath. If you look at what Ghostscript spits out when you run the code I posted at the linked question, it's pretty ugly. And even Inkscape doesn't really do a good job. I just tried Path => Outline stroke in Inkscape (I think that's what the English captions should say), and what came out didn't really look the same as the stroked path.
The "simplest" case would be if you only have non-self-intersecting polylines, polygons or paths that don't contain curves because in general, you can't draw exact "parallel" Bézier curves to the right and the left of a non-trivial Bézier curve that would delimit the stroked area - it's mathematically non-existent. So you would have to approximate it one way or the other. For straight line segments, the exact solution can be found comparatively easily.
The classic way of rendering vector paths with curves/arcs in them is to approximate everything with a polyline that is sufficiently smooth. De Casteljau's Algorithm is typically used for turning Bézier curves into line segments. (That's also basically what comes out when you use the strokepath command in Ghostscript.) You can then find delimiting parallel line segments, but have to join them correctly, using the appropriate linejoin and miterlimit rules. Of course, don't forget the linecaps.
I thought that self-intersecting paths might be tricky because you might get hollow areas inside the path, i.e. the "crossing area" of a black path might become white. This might not be an issue for open paths when using nonzero winding rule, but I'd be cautious about this. For closed paths, you probably need the two "delimiting" paths to run in opposite orientation. But I'm not sure right now whether this really covers all the potential pitfalls.
Sorry if I cause a lot of confusion with this and maybe am not of much help.
This page has a fairly good tutorial on bezier curves in general with a nice section on offset curves.
http://pomax.github.io/bezierinfo/
A less precise but possibly faster method can be found here.
http://seant23.wordpress.com/2010/11/12/offset-bezier-curves/
There is no mathematical answer, because the curve parallel to a bezier curve is not generally a bezier curve. Most methods have degenerate cases, especially when dealing with a series of curves.
Think of a simple curve as one with no trouble spots. No cusps, no loops, no inflections, and ideally a strictly increasing curvature. Chop up all the starting curves into these simple curves. Find all the offset curves of these simple curves. Put all the offset curves back together dealing with gaps and intersections. Quadratic curves are much more tractable if you have the option to work with them.
I think most browsers do something similar to processingjs, as they have degenerate cases even with quadratic curves. For example, look at the curve 200,300 719,301 500,300 with a thickness of 100 or more.
The standard method is the Tiller-Hanson algorithm (Offsets of Two-Dimensional Profiles, 1984, which irritatingly is not on line for free) which creates a good approximation. The idea is that because the control points of each Bezier curve lie on lines tangent to the start and end of the curve, a parallel curve will have the same property. So we offset the start and the end of the curve, then find new control points using these intersections. However, that gives very bad results for sharp curves, so the first step is to bisect the original curve, which is very easy to do to Bezier curves, until it turns through a sufficiently small angle.
Other refinements are needed to deal with (i) intersections between the parallels, on the inside of each vertex; (ii) inserting an arc of a circle to fill the gap on the outside of each vertex; and (iii) adding end-caps - square, butt or circular.
Tiller-Hanson is difficult to implement, but there's a good open-source implementation in the FreeType library, in ftstroke.c (http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/base/ftstroke.c).
I'm sorry to say that it can be quite difficult to integrate this code, but I have used it successfully, and it works well.
Almost all vector graphics applications (like Corel) approximate elliptic arcs with several cubic Bezier curves. I need to add similar functionality to my application. So my question is: how to calculate control points of that Bezier curve?
There are lots of pages explaining how to do this. This paper by Don Lancaster, for example, gives control parameters for divisions of an ellipse into between 2 and 8 cubic splines, with a detailed analysis of the 4-spline case.
I'm trying to create a "parrallel" bezier curve. In my attempts I've gotten close but no cigar. I'm trying to keep a solid 1px offset between the 2 curves (red,blue).
My main goal is use a edge offseting algorythm to expand/shrink a svg path.
Solution
For anyone else who is looking for a solution, I've create a AS3 version.
http://seant23.wordpress.com/2010/11/12/offset-bezier-curves/
I hope you found my math paper useful
Quadratic bezier offsetting with selective subdivision
https://microbians.com/mathcode
From wikipedia: ( http://en.wikipedia.org/wiki/B%C3%A9zier_curve )
The curve at a fixed offset from a given Bézier curve, often called an offset curve (lying "parallel" to the original curve, like the offset between rails in a railroad track), cannot be exactly formed by a Bézier curve (except in some trivial cases). However, there are heuristic methods that usually give an adequate approximation for practical purposes.
You might also see the paper indicated here:
Outline of cubic bezier curve stroke
What you ask for is called a parallel or offset curve in mathematics. The Wikipedia article (quoted above by others) on Bezier curves failed to link to the right article for "offset curve", but I've fixed that a few seconds ago. In the world of vector graphics, that same notion is called stroking the path.
In general, for cubic/Bezier curve the offset curve is a 10th order polynomial! Source: Kilgard, p. 28
If all you want to do is rasterize such offset curves, rather than compute their analytic form, you can for example look at the sources of ghostscript. You could also look at this patent application to see how NV_path_rendering does it.
If you want to covert/approximate the offset curves, then the TUG paper on MetaFog for covering METAFONT to PostScript fonts is a good reading. The METAFONT system, which predated PostScript allowed fonts to be described by the (more mathematically complex) operation of stroking, but PostScript Type 1 fonts only allow filling to be used (unlike PostScript drawings in general) for reasons of speed.
Another algorithm for approximating the offsets as (just two) Beziers (one on each side), with code in PostScript, is given in section 7 of this paper by Gernot Hoffmann. (Hat tip to someone on the OpenGL forum for finding it.)
There are in fact a lot of such algorithms. I found a 1997 survey of various algorithms for approximating offset curves. They assume the progenitor curves are Beziers or NURBS.
It's not possible in general to represent the offset of a cubic Bezier curve as a cubic Bezier curve (specifically, this is problematic when you have cusps or radius of curvature close to the offset distance). However, you can approximate the offset to any level of accuracy.
Try this:
Offset the Beziers in question (what you have already seems pretty decent)
Measure the difference between each original curve and corresponding offset curves. I'd try something like 10 samples and see if it works well.
For any offset that's outside of tolerance, subdivide (using the deCastlejau algorithm for Beziers) and iterate.
I haven't implemented an offset (because the kernels I use already have one), but this seems like something to try.