2013-03-28 2 views
1

В принципе, я хочу нарисовать многоугольник, но хочу, чтобы края выглядели мягкими, а не жесткими. Поскольку форма многоугольника важна, края должны проходить через точки.Как нарисовать замкнутую кривую над множеством точек?

Я нашел монотонные кубические сплайны, чтобы быть точными для открытых кривых (т. Е. Кривых, которые не обертываются сами по себе), но алгоритмы, которые я нашел, предварительно подсчитали точки 0 и N. Могу ли я каким-то образом изменить их на работать с закрытой кривой?

Я реализую это в JavaScript, но псевдокод будет так же хорошо.

+0

ли вы имеете в виду на холсте? –

+0

Не очень важно, так как мне просто нужно выяснить координаты. Но да. SVG тоже будет в порядке, если у вас есть решение, и в этом случае я могу преобразовать его в холст. – Blixt

+0

По краям появляются мягкие, вы имеете в виду, что «вершины кажутся мягкими»? –

ответ

5

There is an easy method (разработан Максимом Шемараевым), чтобы построить (обычно) красиво замкнутые кривые Безье, установленные над множеством точек. Пример:

enter image description here

Ключевые моменты алгоритмом:

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

и примеры кода:

// 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; 
+0

Почему вы не уточняете этот простой метод в своем ответе? Поскольку это стоит, значение ответа полностью зависит от страницы, на которой этот URL не снимается или не перемещается. –

+0

@Asad Да, это имеет смысл – MBo

+0

Спасибо! +1 за отличный ответ. –