admin管理员组

文章数量:1421054

Basically I want to draw a polygon, but I want the edges to appear soft rather than hard. Since the shape of the polygon is important, the edges have to go over the points.

I've found monotone cubic splines to be accurate for open curves (i.e., curves that don't wrap around on themselves), but the algorithms I've found precalculate points 0 and N. Can I somehow change them to work with a closed curve?

I am implementing this in JavaScript, but pseudo-code would just as well.

Basically I want to draw a polygon, but I want the edges to appear soft rather than hard. Since the shape of the polygon is important, the edges have to go over the points.

I've found monotone cubic splines to be accurate for open curves (i.e., curves that don't wrap around on themselves), but the algorithms I've found precalculate points 0 and N. Can I somehow change them to work with a closed curve?

I am implementing this in JavaScript, but pseudo-code would just as well.

Share Improve this question asked Mar 28, 2013 at 20:25 BlixtBlixt 50.3k13 gold badges126 silver badges154 bronze badges 4
  • Do you mean on canvas? – user1726343 Commented Mar 28, 2013 at 20:36
  • Not really relevant, since I just need to figure out the coordinates. But yes. SVG would be ok too if you have the solution, in which case I can convert it to canvas. – Blixt Commented Mar 28, 2013 at 23:38
  • By 'edges appear soft' do you mean 'vertices appear soft'? – Andrew Mao Commented Mar 29, 2013 at 4:42
  • I mean that the angle difference between two edges (connected by a vertex) should be a smooth curve rather than an abrupt change. @MBo's got it right in his answer (see picture), although I would appreciate the same solution for monotone cubic splines. – Blixt Commented Mar 30, 2013 at 2:16
Add a ment  | 

1 Answer 1

Reset to default 8

There is an easy method (developed by Maxim Shemanarev) to construct (usually) good-looking closed Bezier curves set over a set of points. Example:

Key moments of algo:

and sample code:

  // Assume we need to calculate the control
    // points between (x1,y1) and (x2,y2).
    // Then x0,y0 - the previous vertex,
    //      x3,y3 - the next one.

    double xc1 = (x0 + x1) / 2.0;
    double yc1 = (y0 + y1) / 2.0;
    double xc2 = (x1 + x2) / 2.0;
    double yc2 = (y1 + y2) / 2.0;
    double xc3 = (x2 + x3) / 2.0;
    double yc3 = (y2 + y3) / 2.0;

    double len1 = sqrt((x1-x0) * (x1-x0) + (y1-y0) * (y1-y0));
    double len2 = sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));
    double len3 = sqrt((x3-x2) * (x3-x2) + (y3-y2) * (y3-y2));

    double k1 = len1 / (len1 + len2);
    double k2 = len2 / (len2 + len3);

    double xm1 = xc1 + (xc2 - xc1) * k1;
    double ym1 = yc1 + (yc2 - yc1) * k1;

    double xm2 = xc2 + (xc3 - xc2) * k2;
    double ym2 = yc2 + (yc3 - yc2) * k2;

    // Resulting control points. Here smooth_value is mentioned
    // above coefficient K whose value should be in range [0...1].
    ctrl1_x = xm1 + (xc2 - xm1) * smooth_value + x1 - xm1;
    ctrl1_y = ym1 + (yc2 - ym1) * smooth_value + y1 - ym1;

    ctrl2_x = xm2 + (xc2 - xm2) * smooth_value + x2 - xm2;
    ctrl2_y = ym2 + (yc2 - ym2) * smooth_value + y2 - ym2;

本文标签: javascriptHow do I draw a closed curve over a set of pointsStack Overflow