Simple Algorithm For Line Curving - c++

I'm looking for a simple algorithm for line curving (much like fireworks freeform tool).
In my C++ program, a line is a set of ordered points, each point is of (x,y) form.
Assume I have straight line of 5 (just for simplicity) ordered points (the line isn't necessarily parallel to any axis). I pinch the 3rd point and drag it up. I'm expecting to have a new, gaussian-like, curved line. It doesn't really matter how I implement the "Points" and "Lines", but keep in mind I should add more points to the new expected line so it'll be curved, refined and flowing (and not with line breaks).
I thought of using a gaussian function but I need the ability of moving the curved part (see picture below).
Thanks in advance!

You need a B-spline or a Bezier curve to approximate your shape.
There is a nice interactive demo of Bezier splines so you can play with to see the effect. A sample screenshot below:
Depending on your OS and development environment, there are probably already a number of tools or APIs available.

Related

B-Spline for any number of control points

I am currently working on a soft body system using numeric spring physics and I have finally got that working. My issue is that everything is currently in straight lines.
I am aiming to replicate something similar to the game "The floor is Jelly" and everything work except the smooth corners and deformation which currently are straight and angular.
I have tried using Cubic Bezier equations but that just means every 3 nodes I have a new curve. Is there an equation for Bezier splines that take in n number of control points that will work with loop of vec2's (so node[0] is the first and last control point).
Sorry I don't any code to show for this but i'm completely stumped and googling is bringing up nothing.
Simply google "B-spline library" will give you many references. Having said this, B-spline is not your only choice. You can use cubic Hermite spline (which is defined by a series of points and derivatives) (see link for details) as well.
On the other hand, you can also continue using straight lines in your system and create a curve interpolating the straight line vertices just for display purpose. To create an interpolating curve thru a series of data points, Catmull-Rom spline is a good choice for easy implementation. This approach is likely to have a better performance than really using a B-spline curve in your system.
I would use B-splines for this problem since they can represent smooth curves with minimal number of control points. In addition finding the approximate smooth surface for a given data set is a simple linear algebra problem.
I have written a simple B-spline C++ library (includes Bezier curves as well) that I am using for scientific computations, here:
https://github.com/feevos/bsplines
it can accept arbitrary number of control points / multiplicities and give you back a basis. However, creating the B-spline curve that fits your data is something you have to do.
A great implementation of B-splines (but no Bezier curves) exists also in GNU GSL (
https://www.gnu.org/software/gsl/manual/html_node/Basis-Splines.html). Again here you have to implement the control points to be 2/3D for the given basis, and fix the boundary conditions to fit your data.
More information on open/closed curves and B-splines here:
https://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/index.html

RANSAC line3d fitting by 3d line segments

I am having many 3d line segments. some of them are nearly parallel
and some are oriented in to different direction. I want to avoid
outliers and to get the best line 3d to represent the given 3d line
segments.
I am bit confused how RANSAC method apply for this case...
should i find a random line first or should i consider this as a given 3d point problem.?
can anyone post me the stucture to be followed when implenting this in c++. thanks
RANSAC is a good tool to fit data to a model. If you had a single 3D line in a collection of segments, by running RANSAC and selecting the line that maximized the amount of inliers would be enough. However, since you have many lines in the collection, you should try a different approach (even a non-RANSAC one, as I tell you later).
For example, you can run first RANSAC trying to find the line that matches as many segments as possible. After finding that line, remove the inlier segments from the collection and run RANSAC again.
To create a line, you only need a segment, so building the line model is quite easy.
To decide on whether a segment fits a line, you may compute the angle between both with the dot product (the closer to 0 the better) and the distance from the middle point of the segment to the line.
Also note that you can filter out very small segments at as first step. You could save some iterations later and avoid noisy results.
I can think of a Hough transform approach as well. Since you can create a line from each segment, you can get the parameters of its line (normal or directional vector and distance to origin), quantize them to some acceptable bin-size and add a vote to those parameters in a matrix. Finally, your lines lie in the peaks of the vote matrix.

How to compute overlap between nearly parallel two line segments

I have equally oriented (but not exactly parallel) 2D line segments. I want to find out a line segment which is given maximum overlap with a given line segment.
I think scalars can be used to compute this effectively, but my geometry is too poor to figure out this.
for example, in the below figure; dark line is assumed as the given line and red highlighted line segment is given the maximum coverage (or longest overlap, not sure whether my terminology is correct) when compared to other line segments.
My objective is to find the best line which represents the dark line
from the other line segment sets.
what i want to find is any line which has maximum coverage to a given line. that mean, i want to avoid line segments whose starts and ends are out of the ends of the given line segment. also, when many lines give their maximum coverage for the given line, then i want to avoid shorter line and need a long one. idea is to find another line which we can consider instead of that given line segment
helps are highly appreciated as later i want to implement this in programming environment.
thanks
example 1
example2
to say what i meant 'coverage', i will say
in above figure: the projected blue line completely lay within the dark black line. but it is too short. But, large portion of the red line (projected line) lay within the black line though some part of the red line go out. green line is completely out of the black line. so, i can say red line give maximum coverage with black line..(does my idea correct?)
Project ends of a candidate segment onto the target segment.
Calculate distance between projections.
[optionally] Multiply by cos of angle between the segments.
Note about #1: in this context projection on a segment means the closest point lying on that segment. One of ways is:
project a point on infinite line going through the segment
if the projection is inside of the segment - take it
if the projection is outside of the segment - take the closest segment end
I don't know your question are on graphics processing or computational functions.
But for graphics, this question belongs to computer vision subject, what you want is maybe the Hough Line Transform algorithm.
However, if you question is simpler than this, what you want maybe the SAD algorithm

Create smooth line to join N points in 3 dimensions

I have N points in 3-dimensional space. I need to join them using a line. However, if I do that using a simple line, it is not smooth and looks ugly.
My current approach is to use a Bezier curve, using the DeCasteljau algorithm for 4 points, and running that for each group of 4 points in my data set. However, the problem with this is that since I run it on say points 1-4, 5-8, 9-12, etc., separately, the line is not smooth between 4-5, 8-9, etc.
I also looked for other approaches; specifically I found this article about Catmull-Rom splines, which seem even better suited for my purpose, because the curve passes through all control points, unlike the Bezier curve. So I almost started implementing that, but then, I saw on that site that the formula works "assuming uniform spacing of control points". That is not the case for my problem.
So, my question is, what approach should I use -- Bezier, Catmull-Rom, or something completely different? If Bezier, then how to fix the non-smoothness between 4-5, 8-9, etc.? If Catmull-Rom, why won't the formula work if points are not evenly spaced, and what do I need instead?
EDIT: I am now pretty sure I want the Catmull-Rom spline, as it passes every control point which is an advantage for my application. Therefore, the main question I would like answered is why won't the formula on the link I provided work for non-uniformly spaced control points?
Thanks.
A couple of solutions:
Use a B-spline. This is a generalization of Bezier curves (a Bezier curve is a B-spline with no internal knot points.)
Use a cubic spline. Cubic splines are particularly easy to calculate. A cubic spline is continuous in the zero, first, and second derivatives across the control points. The third derivative, the cubic term, suffers a discontinuity at the control points, but it is very hard to see those discontinuities.
One key difference between a B-spline and a cubic spline is that the cubic spline will pass through all of the control points, while a B-spline does not. One way to think about it: Those internal control points are just suggestions for a B-spline but are mandatory for a cubic spline.
A meaningful line (although not the simplest to evaluate) can be found via Gaussian Processes. You set (or infer) the lengthscale over which you wish the line to vary (i.e. the smoothness of the line) and then the GP line is the most probable line through the data given the lengthscale. You can add noise to the model if you don't mind the line not passing through the data points.
Its a nice interpolation method because you can also obtain the standard deviation of your line. The line becomes more uncertain when you don't have much data in the vacinity.
You can read about them in chapter 45 of David MacKay's Information Theory, Inference, and Learning Algorithms - which you can download from the author's website here.
one solution is the following page in wikipedia: http://en.wikipedia.org/wiki/Bézier_curve, check the generalized approach for N control points.

Drawing a Smooth Line from Tablet Input

As the user drags their stylus across the tablet, you receive a series of coordinates. You want to approximate the pen's path with a smooth line, trailing only a few sample points behind it. How would you do this?
In other words, how would you render a nice smooth responsive line as a user draws it with their tablet? Simply connecting the dots with straight lines is not good enough. Real drawing programs do a much better job of curving the line, no matter how close or far the sample points are. Some even let you give them a number to indicate the amount of smoothing to be done, accounting for jittery pens and hands. Where can I learn to do this stuff?
I know this is an old question but I had the same problem and I came with 2 different solutions:
The first approach is use two resolutions: One , when the user is inserting the path points connecting them with straight lines. Two , when the user finish the stroke delete the lines and draw the spline over. That should be smoother than the straight lines.
The second approach it is to smooth the new points with a weighted mean of the sampled points. So each time you get a new point [x1,y1] instead of painting it directly, you take the previous points [x2,y2] and create a new intermediate point with the weighted mean of the two points. The pseudocode could be something like:
newPoint = [x1,y1];
oldPoint = [x2,y2];
point2Paint = [(x1*0.3) + (x2*0.7), (y1*0.3) + (y2*0.7)];
oldPoint= newPoint;
Being 0.7 and 0.3 the coefficients for the weighted mean ( You can change them to get your desired smoothing :)
I hope this would help
UPDATE Dec 13: Here it is an article explaining different drawing methods, there are good concepts that can be applied (edge smoothing, bezier curves, smooth joints)
http://perfectionkills.com/exploring-canvas-drawing-techniques
I never had to implement these (only for academic purposes), but you may want to take a look at wikipedia's interpolation article.
Extracted from the article:
interpolation is a method of constructing new data points within the range of a discrete set of known data points.
In engineering and science one often has a number of data points, as obtained by sampling or experimentation, and tries to construct a function which closely fits those data points. This is called curve fitting or regression analysis. Interpolation is a specific case of curve fitting, in which the function must go exactly through the data points.
Hope it helps.