how to interpret a freetype glyph outline when the first point on the contour is off curve - c++

I'm actually working on a renderer that converts freetype glyphs into polylines to control a laser marking system. The problem I have is that I don't know how to handle correctly a contour beginning with an off curve point (99.9% begin with on curve points!). I've searched quite a while now for informations but I couldn't find anything useful.
Thanks for your help

FreeType uses three types of points: on-curve, quadratic control points (also known as 'conic') and cubic control points. The quadratic control points are grouped with on-curve points on either side of them to form the three points needed to define a quadratic Bézier spline. The cubic control points must occur in pairs, and are grouped with on-curve points on either side to make up the four points needed for a cubic Bézier spline.
However, there is a short-hand notation for quadratic points only. Where quadratic points occur next to each other, an on-curve control point is interpolated between them. And there is another convention, that if a closed path starts with a quadratic point, the last point of the path is examined, and if it is quadratic, an on-curve point is interpolated between them, and the path is taken to start with that on-curve point; if the last point is not a quadratic control point, it is itself used for the start point.
If you want to see exactly how this is done, please look at the FreeType source code. The function FT_Outline_Decompose traverses a path and converts it into a series of lines and curves of both types. It's in this file:
http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/base/ftoutln.c
The part of especial interest starts with this comment (note again that 'conic' means the same as 'quadratic' in this context):
/* first point is conic control. Yes, this happens. */

Related

Project a line segment onto a mesh

What are the graphic/mathematical algorithms I have to look for in order to achieve the red line in the following image?
Explaining it better: I need to plot two points on the mesh and then generate a straight line segment from one point to the next. This line segment would be formed by new vertices created on every single edge in its way.
I'm currently working with CGAL and Libigl, but none of them seem to have the solution. I have tried CGAL::Surface_mesh_shortest_path but it adds too much overhead (code runs very slowly) and the line would not be guaranteed to be straight depending on the mesh deformation.
Ignoring whatever you mean as "straight", here is one simple algorithm I can think of that would produce images to the one similar shown in the question. There is no guarantee of what is produced being the shortest path. I'm just spitballing here with no knowledge on the topic, there are probably better ways.
Pick 4 variables:
The starting point
The ending point
The line's normal
A marching constant
Let's calculate a few constants from the variables:
Direction = ending point - starting point
Increment vector = normalize(Direction) * marching constant.
Begin from the starting point and march towards your ending point by some constant, checking above and below your current position for where you are on the mesh. You use the line's normal to understand the "up" and "down" directions in order to perform intersection tests.
On each intersection test, if you do not intersect for both the up and down directions, then the normal you chose will not work for the given two points and mesh, and you'll have to try a different normal. If you do end up intersecting from one of the directions, you will need to add 2 points to your final line: a point on the calculated direction line closest to the start that lies on the triangle, and a point on the calculated direction line farthest from the start that lies on the triangle. If there's both an intersection on the up and down directions, choose the up direction to work with.

How to split a general closed polygon by a line segment

I need a good (robust) algorithm for splitting a polygon into two sets(left/right) by a line segment. My polygon representation is simply a list of integer coordinates(ordered clock wise, never self intersecting) and the line segment is represented by a start and end point. The line always starts and ends outside the polygon, i.e. intersects the polygon an even number of times.
Here is an example:
The output of the algorithm should be the two sets(travelling clock wise):
Left: HABCH, FGDEF
Right: HCDGH, BAB, FEF
I can identify the points A-H by iterating the polygon and checking if a polygon segment crosses the line, taking care to respect border cases. I can also determine which side each multi-line belongs to. I cannot though, for the life of me, decide how to string these segment together.
Before you suggest a general purpose clipping library: I am using boost polygon which is very good at clipping polygons against each other, but I haven't found any library which let's you clip a polygon against a line segment and it is not possible in general to turn the line segment into a polygon which I could clip with.
EDIT: I had missed FEF and the fact that a polygon can have parts on both sides of the line segment.
Ok, here is a rather simple recipe of how to arrive at the answer:
Start with the set of intersection points ordered by traveling the contour clockwise:
ABCDEFGH
Sort them according to distance from the start of line:
HCFEDGBA
We also need to remember for each point if it is a left-to-right or right-to-left intersection.
Start with any point. Let's say G. Follow the contour clockwise and add GH
to the current polygon.
Now we need to travel along the line. The
direction depends on which side of the line we are. We are on the
right side, so we need to pick the value to the right of H in the
sorted set: C. Add HC to the current polygon.
Follow the contour clockwise and add CD to the current polygon.
We are on the right side, so we need to pick the value to the right of D in the sorted set: G. Add DG to the current polygon.
We have now reached the
starting point, so let's save the polygon(GHCDG) and remove used
points from the list.
Start over with another point.
For each intersection of the polygon border with the line segment:
Add a new point to the polygon.
Remember the new points in a new-point set.
Add the original polygon to the polygon set.
For each pair of points in the new-point set:
For each polygon in the current polygon set:
If the line segment between the points is completely inside the polygon.
Replace the polygon in the polygon set with two polygons
generated by dividing the original polygon along the line
segment between the points.
For each polygon in the polygon set:
Add it to the Left result set or the Right result set.
(Note this may not be possible.
Consider your example of the segment starting between C and F:
You will end up with a polygon (GABCFG) that touches both
sides of the dividing segment. Is that a Left or a Right?
I've solved something similar once and I gave up trying to be clever.
Run round all the vertices making them into connected line segments,
starting a new segment with a new point every time you intersect the
cutting line.
Find all segments which share an end point and join them back up into one longer one.
Connect all the open ends.

Draw a bezier curve(s) with a set of points from a vector

I was wondering what would be the best and less complicated way of drawing a bezier curve in c++ with a set of points (roughly 100+ points) that are stored inside a vector
From my understanding:
-Bezier curves consist of 4 control points, the points in the middle dictate the direction/tangent of the curve
Would one possible method be to breakdown the points into different segments and from each segment determine the control points and tangents?
It is called a cubic spline and if you search you might find some C++ code for it. I used the free Fortran code from Numerical Recipes Online and ported it to C# with no problems.
Would one possible method be to
breakdown the points into different
segments and from each segment
determine the control points and
tangents?
Yes, basically one connects the line segments end-to-end such that the slope approaching the end of the line segment is equal on both sides of the connection point. This is called a cubic spline. You can find algorithms for this here.

How do bezier handles work?

On Wikipedia I found information about bezier curves and made a function to generate the inbetween points for a bezier polygon. I noticed that Expression Design uses bezier handles. This allows a circle to be made with 4 points each with a bezier handle.
I'm just not sure mathematically how this works in relation with the formula for bezier point at time T. How do these handle vectors work to modify the shape? Basically what's there relation to the bezier formula?
Thanks
Basically, the 4 points used in the cubic bezier formula are the 2 points the curve is between, plus the two points of the handles on that "side" of the first two points (1 handle from each of the first points). If there are double handles on each point, the handles on the "opposite" side of the points from the curve currently being calculated are ignored (they're used for generating the curve that comes out of the opposite side).
The actual generation method used for cubic bezier curves is outlined on the Wikipedia page you linked in your question.
The 4 points of a Bezier segment are the two endpoints of the segment and two handles, one per endpoint. The handles determine the initial direction of the line as it leaves the endpoint. The distance from the handle to the endpoint determines the amount of "pull" that the handle exerts on the path.
Often you will find multiple Beziers connected end to end, with the endpoint of one being shared as the starting point of the next. This guarantees an unbroken curve. If the handles on either side of a point are directly across from each other, the angle at the joint will match up; if the handles are also the same distance from the point, the angle will be completely smooth and there will not be a visible discontinuity at the point.
An interesting property of Bezier segments is that the curve will fit entirely within the parallelogram defined by the 4 points.
What I have been describing is the most common form of Bezier, the cubic. There is also a quadratic which only has a single handle between the two endpoints; the most common application is TrueType fonts.

Connecting Catmull-Rom splines together and calculating its length?

I'm trying to create a class which takes in any number of points (position and control) and creates a catmull-rom spline based on the information given.
What I'm doing - and I'm really unsure if this is the right way to do it - is storing each individual point in a class like so:
class Point
{
public:
Vector3 position;
Vector3 control;
}
Where obviously position is the position of the point and control is the control point.
My issue is connecting up the splines - obviously given the above class holding a point in the spline array indicates that any given position can only have one control point. So when having three or more points in a catmull rom spline the various individual catmull-rom splines which are being connected share one position and one control with another such spline.
Now with position being the same is required - since I want to create splines which are continuous between themselves. However I really wonder, should the control points also be the same between the two splines? With a bit of fiddling of the control points I can make it appear to be transitioning smoothly from one spline to another however I must emphasize that I'm not sure if the way they are transitioning is consistent with how catmull-rom splines form their shape. I'd much rather do it correctly than sit on my hands and rationalize that it's good enough.
Obviously the second part of my question is self explanatory: Given two control and position points how do I calculate the length of a catmull-rom spline?
To define the spline between two control points, the Catmull-Rom spline needs the control points and the tangent vector at each control point. However, the tangent vector at internal (i.e. non-endpoint) control points is defined by the control points on either side of it:
T(Pn) = (Pn+1 - Pn-1) / 2. For closed curves, the spline is completely defined by the set of control points. For non-closed curves, you need to also supply the tangent vector at the first and last control point. This is commonly done: T(P0) = P1 - P0 and T(Pn) = Pn - Pn-1.
Thus, for closed curves, your data structure is just a list of control points. For general splines, it's a list of points plus the first and last normal vector.
If you want to have a cardinal spline, then you can add a weighting factor to the tangent vector calculation as in the Wikipedia article.
To calculate the length of such a spline, one approach would be to approximate it by evaluating the spline at many points and then calculating the linear distance between each neighboring pair of points.
With regards to measuring the lengths, you can do this with calculus since its a polynomial spline. You need to do integrate the distance function across the line. Its described quite well on Wikipedia...