7

I am a beginner in SVG.

I need an SVG curve that passes through a list of points. It is a math function that is calculated in C++ and the output result is supposed to be written in an SVG file. My problem is that the path tag in SVG does not pass through all points. Instead, it skips some of them in the middle and just tends to them. Does SVG have any facility to pass the curve through the whole points and bend the curve appropriately in automatic way?

Mathematical Curve

<svg height="400" width="450">
  <path d="M 80 90 C 190 40, 300 60, 380 160" stroke="blue" stroke-width="5" fill="none" />
  <path d="M 80 90 L 190 40, 300 60, 380 160" stroke="green" stroke-width="1" fill="none"/>
  <g stroke="black" stroke-width="3" fill="black">
    <circle id="pointC" cx="80" cy="90" r="3" stroke="black"/>
    <circle id="pointA" cx="190" cy="40" r="3" stroke="green"/>
    <circle id="pointC" cx="300" cy="60" r="3" stroke="red"/>
    <circle id="pointB" cx="380" cy="160" r="3" stroke="blue"/>
  </g>
  Sorry, your browser does not support inline SVG.
</svg>
barej
  • 1,330
  • 3
  • 25
  • 56

3 Answers3

5

If you need to draw smooth curve through many points, considering using Catmull Rom splines or Overhauser splines. Both algorithms will result in a cubic spline with C1 continuity at the segment junctions. Also, they are easier to implement than implementing C2 B-spline interpolation as the latter requires you to solve a linear equation set. You can also convert Catmull Rom spline or Overhauser spline back to Bezier form easily.

fang
  • 3,473
  • 1
  • 13
  • 19
  • 1
    please let me know if i understood catmull-rom correctly. for end points such as P0 and P1, the control point is (2/3)P0+(1/3)P1 and for the rest of points such as consequence of Pa, Pb, Pc, the control point before Pb is Pb+(1/6)*(Pa-Pc) and the control point after Pb is Pb+(1/6)*(Pc-Pa). Am I correct? – barej Dec 22 '14 at 16:14
  • 1
    @OP: Yes. That is correct. However, the formula you listed are for uniform Catmull Rom spline, which assumes uniform parametrization for the data points (i.e., t0=0.0, t1=1.0, t2=2.0,...etc). It will be better to use Centripetal Catmull Rom spline (refer to Wiki page), which can produce better result when the data points have uneven distribution. – fang Dec 22 '14 at 18:54
2

in SVG path thee Bezier curve is approximation not interpolation so it is usually not passing through all the control points.

Sp what to do:

  1. use interpolation cubic curve and convert it to Bezier

    • Look here: Interpolation cubic to Bezier cubic (needed this for similar reasons like you) I use a specific interpolation cubic there with connectivity C1 (position and 1st derivation) the translation to Bezier is there so you can use it just convert the control points ... Do not forget to 3x multiple only first and last control point for the whole Bezier path not for each Bezier patch !!!
  2. use many lines instead of single Bezier

    this will be choppy of coarse (depending on the lines density) just interpolate enough points and connect them by lines

  3. duplicate control points

    if you have multipled control points (3x) then the Bezier will go through this point. So if you have curve points: p0,p1,p2,p3,... then do multiple Beziers from them like this:

    p0,p0,p0,p1
    p0,p0,p1,p2
    p0,p1,p2,p3
    p1,p2,p3,p3
    p2,p3,p3,p3
    p3,p3,p3,p4
    p3,p3,p4,p5
    p3,p4,p5,p6
    p4,p5,p6,p6
    p5,p6,p6,p6,...
    

    this will go through the points p0,p3,p6,... so you still need to evaluate the non passing control points to ensure desired connectivity

Spektre
  • 49,595
  • 11
  • 110
  • 380
0

If you need to draw curve through 4 points only, look at the solution in this topic and linked tinaja page.
If you have to draw smooth curve through many points, consider building interpolation cubic splines (NR book, page 113), than transform these splines to Bezier form (change bazis from polynomial to Bernstein)

Community
  • 1
  • 1
MBo
  • 77,366
  • 5
  • 53
  • 86