Question about the implementation of Bezier Curves?

I have read some tutorials for bezier curve such as this one http://www.codeproject.com/KB/recipes/BezirCurves.aspx.

The basic idea to create bezier curve is to use some control points and make decision how many new points need to be created. And then interpolate those new points.

Here is the question:

Assume I have 1000 points and I would like to interpolate 2000 points more. The number of control points I want to use is 5. The parameter t is in the range of [0, 1].

Givens points P0, P1, P2, P3, P4, P5, P6, ...P1000. I can use P0-P4 to generate new points, then what's next? use P5-P9 to generate new points??? I can immediately see there is a sudden transform between P4 and P5.

How can I solve this issue?

Thank you

///////////////////////////////////////////////////// Hello Stargazer712,

I understand your comments until it reaches the implementation method.

Assume we have the following points:

A1->A2->A3->A4->A5->A6->A7->A8 initial points

You said that we need to add a new point at the midpoint of every other pair.

My question is what the order of the new point is?

Let use use this annotation (A1+A3)/2 == A12

Now generated new points are

A13 A24 A35 A46 A57 A68 (this is what you mean "every other pair"?

Where should I insert those points into the original list?

The contour I am working on is extracted from binary image. The generated contour is zig-zag shape. After I apply this smooth method, it shape doesn't improve too much. I think the major reason is that the neighbors are near each other and make the interpolation not that useful.

Thank you

////////////////////////////////////////////////////

9
задан q0987 18 August 2010 в 10:02
поделиться

1 ответ

Я думаю, что вы пытаетесь создать плавную кривую, интерполируя точки. Для этого вам нужно понять следующее о кривых Безье:

Допустим, у нас есть две кривые с точками A1, A2, A3, A4 и B1, B2, B3 и B4.

Если эти две кривые заканчиваются в одной и той же точке, и если последняя контрольная точка первой кривой коллинеарна первой контрольной точке следующей, то кривые будут гладкими. Так, в нашем примере, если:

  • A4 == B1
  • A3, A4 и B2 коллинеарны (то же самое, что сказать, что A3, B1, B2 коллинеарны)

Тогда кривые будут гладкими.

Чтобы взять произвольный список точек и построить гладкую кривую, нам нужно заставить эти два условия быть верными.

Для этого, допустим, мы начнем с набора точек:

Initial Points

Чтобы выполнить вышеуказанные условия, добавим несколько дополнительных точек. Поместим новую точку в среднюю точку каждой другой пары, как показано на рисунке:

With meta points

Теперь мы можем построить кривые Безье между точками 0-3, 3-6, 6-9 и т.д., и мы можем быть уверены, что они образуют плавную кривую:

Curve drawn

Надеюсь, это поможет!

EDIT: Вот простая программа на python, которая реализует именно то, что было показано выше (и я имею в виду именно это). Вам нужно установить python и PIL:

from PIL import Image
import math

#
#   draws a single point on our image
#
def drawPoint( img, loc, size=5, color=(0,0,0) ):
    px = img.load()
    for x in range(size):
        for y in range(size):
            xloc = loc[0] + x - size/2
            yloc = loc[1] + y - size/2
            px[ xloc, yloc ] = color


#
#   draws a simple bezier curve with 4 points
#            
def drawCurve( img, points ):

    steps = 20
    for i in range(steps):

        t = i / float(steps)

        xloc = math.pow(1-t,3) * points[0][0] \
             + 3*t*math.pow(1-t,2) * points[1][0] \
             + 3*(1-t)*math.pow(t,2) * points[2][0] \
             + math.pow(t,3) * points[3][0]
        yloc = math.pow(1-t,3) * points[0][1] \
             + 3*t*math.pow(1-t,2) * points[1][1] \
             + 3*(1-t)*math.pow(t,2) * points[2][1] \
             + math.pow(t,3) * points[3][1]

        drawPoint( img, (xloc,yloc), size=2 )


#
#   draws a bezier curve with any number of points
#
def drawBezier( img, points ):

    for i in range(0,len(points),3):
        if( i+3 < len(points) ):
            drawCurve( img, points[i:i+4] )


#
#   draws a smooth bezier curve by adding points that
#   force smoothness
#
def drawSmoothBezier( img, points ):

    newpoints = []

    for i in range(len(points)):

        # add the next point (and draw it)
        newpoints.append(points[i])
        drawPoint( img, points[i], color=(255,0,0) )

        if( i%2 == 0 and i>0 and i+1<len(points) ):

            # calculate the midpoint
            xloc = (points[i][0] + points[i+1][0]) / 2.0
            yloc = (points[i][1] + points[i+1][1]) / 2.0

            # add the new point (and draw it)
            newpoints.append( (xloc, yloc) )
            drawPoint( img, (xloc, yloc), color=(0,255,0) )

    drawBezier( img, newpoints )



#   Create the image
myImage = Image.new("RGB",(627,271),(255,255,255))

#   Create the points
points = [  (54,172), 
            (121,60), 
            (220,204), 
            (284,56), 
            (376,159), 
            (444,40), 
            (515,228), 
            (595,72) ]

#   Draw the curve
drawSmoothBezier( myImage, points )

#   Save the image
myImage.save("myfile.png","PNG")

Линия будет следовать шаблону точек. Если ваш результат выглядит зигзагообразно, это потому, что так выглядели линии.

11
ответ дан 3 November 2019 в 00:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: