1

I've googled a lot, but all algorithms I found used equations for finding control points. I've thought there is simpler solution to do it and found some implementation in ExtJS source code: http://docs-devel.sencha.com/extjs/4.1.2/source/Draw.html#Ext-draw-Draw-method-getAnchors. It uses angles betweeen nearest points of line to detect control points and some hacks.

Can somebody define what kind of algorithm for searching control points is this? I am stuck in manipultation with PI and angles. May be there is more detailed and cleaner explanation, or common idea for this way of solving the problem?

Guy Fawkes
  • 2,313
  • 2
  • 22
  • 39

1 Answers1

3

It's Catmull-Rom fitting: the code tries to find an appropriate tangent through point X, based on the location of points X-1 and X+1, such that the tangent is parallel to the line (X-1)--(X+1), and then fiddles with the control points that yields, to make sure the "incoming" and "outgoing" tangents yield an aesthetically pleasing curve.

enter image description here

  1. have points
  2. assume tangent equal to (p-1)--(p+1)
  3. that generally looks horrible
  4. scale control points a little for better fit

How you do step 4 is technically no longer Catmull-Rom, because genuine Catmull-Rom splines stop once the tangent's been set up. The usual approach if you do need a step 4 is to scale the points in based on projected distance: if you project point X on the line (X-1)--(X+1), it'll rarely ever be exactly in the middle of the line, but at some distance v% from point X-1 and distance (100-v)% from point X+1, so you scale the found tangent accordingly.

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
  • 1
    Can you describe what parts of code match to steps of algorithm? I still cannot describe how part 4 works in Sencha code. – Guy Fawkes Feb 21 '15 at 01:44
  • 1
    look for the "One last adjustment, make sure that no control anchor point extends vertically past" part in the file you linked – Mike 'Pomax' Kamermans Feb 21 '15 at 08:03
  • 1
    I read articles about Catmull-Rom, but didn't found explanation like your. All formulas are like this: 0.5f * ((2 * p1) + (p2 - p0) * t + (2*p0 - 5*p1 + 4*p2 - p3) * t * t + (3*p1 -p0 - 3 * p2 + p3) * t * t * t); } May be in Sencha code used not another version of algorithm? – Guy Fawkes Feb 21 '15 at 21:53
  • 1
    Where in the code do you see it do that? As for finding an explanation "like mine", the cubic hermite algorithm can be explained in two very different ways - I gave the procedural explanation, but if you like I can give you the matrix explanation too: the initial curve is formed using [1 t t² t³] * [1 0 0 0 ; -3 3 0 0 ; 3 -6 3 0 ; 1 3 -3 1] * [p2 v1 v2 p3], where `v1` is `p2 - (p3-p1)/12` and `v2` is `p3 + (p4-p2)/12`. But, that's far less understandable, especially since most people have forgotten all their linear algebra by the time they post here ;) – Mike 'Pomax' Kamermans Feb 22 '15 at 17:53
  • 1
    (basically there's usually at least two completely different way to explain geometrical construction algorithms. For curves, I can think of at least three: 1) procedural using plain text, 2) as matrix operations using linear algebra, and 3) as parametric function expressions using calculus. All three will *look* wildly different if you're not familiar with the subject, but they all describe the exact same thing) – Mike 'Pomax' Kamermans Feb 22 '15 at 17:59
  • 1
    Yeah, you are right about linear algebra. But I didn't found procedural explanation in WWW. Here: http://www.cs.cmu.edu/~462/projects/assn2/assn2/catmullRom.pdf I read: "The parameter τ is known as “tension” and it affects how sharply the curve bends at the (interpolated) control points (figure 2). It is often set to 1/2 but you can use any reasonable value for this assignment." Then, manipulations with angles in code and control points used for Bezier curves (in SVG renderer). So it looks like mix of two algorithms. – Guy Fawkes Feb 23 '15 at 08:48
  • 1
    tension is the "free" parameter in Catmull-Rom curves (http://pomax.github.io/bezierinfo/#catmullconv), and you can either try to fiddle with it, or just manipulate the control points you find directly (by moving them along the control tangent). The latter which tends to be far cheaper. – Mike 'Pomax' Kamermans Feb 23 '15 at 19:12