How do I draw a closed curve over a set of points?

2019-04-16 00:20发布

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.

1条回答
成全新的幸福
2楼-- · 2019-04-16 01:13

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

enter image description here

Key moments of algo:

enter image description here enter image description here enter image description here enter image description here

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;
查看更多
登录 后发表回答