kookoo121
kookoo121

Reputation: 1136

How to get connect two part of curve and get the points position of connecting curve?

I have two parts of curve. The points position(x,y) of curve have been known. How to connect them and get the position of the connecting curve?Here is a similar question.similar question He said to use Bezier curves. But in my opinion,usually, the fitting curve not pass through the control points. So if i select some points from two parts of curve as control points, the fitting result may be as following picture. That is not my goal.Can somebody give me some advice?

enter image description here

enter image description here

Upvotes: 3

Views: 2260

Answers (3)

Use a Catmull-Rom curve, which is related to Bezier curves and easy to convert into Bezier form, with the benefit that is goes "through" points, instead of merely being controlled by them. For the fine details see http://pomax.github.io/bezierinfo/#catmullconv, but we basically need those two end points, and two points outside of the curve that ensure we have the correct tangent at our two on-curve points:

enter image description here

p2 and p3 are "your" points, and p1 and p4 are somewhat arbitrary: we just need to make sure that the line p1--p3 is parallel to the tangent at p2 (tangent and its parallel line indicated in bluish purple), and similarly that the line p2--p4 is parallel to the tangent at p3 (tangent and its parallel line indicated in pinkish). A generally easy approach is to just project points p2 and p3 onto the parallel lines.

As long as we make sure that's true, we can form the connecting segment as a Catmull-Rom segment with curve coordinates (p1,p2,p3,p4). If there is no Catmull-Rom drawing primitive, though, we can trivially draw it as a Bezier curve, by using the following cubic Bezier curve coordinates:

  1. start point: p2
  2. control point 1: p2 + (p3-p1)/(6*t)
  3. control point 2: p3 - (p4-p2)/(6*t)
  4. end point: p3

The t value here is the tension of the Catmull-Rom curve; the higher you make this, the "tighter" the join looks (with the default tension in most graphic contexts that support Catmull-Rom simply being 1).

Some example values:

enter image description here

Note that in each example the tangent direction at points p2 and p3 are preserved, but the length of the tangent vector is different, leading to very tight, to nice, to way too loose fittings.

Upvotes: 4

MooseBoys
MooseBoys

Reputation: 6793

Don't rule out Bezier curves. You're correct that the curve often doesn't intersect the control points, but the endpoints do and you can use this to constrain the form of the curve.

To be more specific, you can join the lines by constructing a new quadratic Bezier curve - use the endpoints of your two lines as the endpoints of the curve, with the midpoint being the intersection of two imaginary straight line segments extended from the ends of the current line.

Bezier

In the above example, the red circles are the fixed endpoints of the curve, the green lines are the extended lines, the blue circle is their intersection point (used as the control point), and the blue line is the approximate curve you'll end up with.

Edit: After thinking about this a bit more, you probably want to use a cubic curve, and have two blue control points, one on each green line. Positioning each one L/2 distance away from the endpoints, where L is the straight-line distance between the red endpoints, would probably yield good results. The problem with a quadratic curve is that as the green lines approach parallel, the quadratic curve will end up with a sharp corner near the control point. At parallel, they don't actually intersect at all. Using a cubic curve will produce a much rounder line, and doesn't have any issue with parallel tangents. For example, in the image below, the top curve uses quadratic (one control point) and the bottom one uses cubic (two control points).

Bezier2

Upvotes: 0

Humam Helfawi
Humam Helfawi

Reputation: 20264

As I commented Splines could be a better solution than Bezier in this case. However, you may also use a more simple one. you have 4 points (red). Try to fit them in Polynomial (3rd degree since you have just 4) using this formula:

A x^3 + B x^2 + C x + D = y

You have 4 Points (P0,P1,P2,P3):

A x0^3 + B x0^2 + C x0 + D = y0
A x1^3 + B x1^2 + C x1 + D = y1
A x2^3 + B x2^2 + C x2 + D = y2
A x3^3 + B x3^2 + C x3 + D = y3

Solving this system of linear equation will give you the values of A,B,C,D.

To get the part of the curve that is missing:

for(auto x=P1.x; x<P2.x; ++x){
    auto y=A*x*x*x + B*x*x + C*x + D;
    cv::circle(image,cv::Point(x,y),.......);
}

Upvotes: 0

Related Questions