2010-08-18 4 views
9

J'ai lu quelques tutoriels pour bezier courbe comme celui-ci http://www.codeproject.com/KB/recipes/BezirCurves.aspx.Question sur la mise en œuvre des courbes de Bézier?

L'idée de base pour créer une courbe bezier est d'utiliser certains points de contrôle et de décider combien de nouveaux points doivent être créés. Et puis interpolez ces nouveaux points.

Voici la question:

Supposons que j'ai 1000 points et je voudrais interpoler 2000 points de plus. Le nombre de points de contrôle que je veux utiliser est 5. Le paramètre t est dans la plage [0, 1].

Points Givens P0, P1, P2, P3, P4, P5, P6, ... P1000. Je peux utiliser P0-P4 pour générer de nouveaux points, alors quelle est la prochaine étape? utilise P5-P9 pour générer de nouveaux points ??? Je peux voir immédiatement qu'il y a une transformation soudaine entre P4 et P5.

Comment puis-je résoudre ce problème?

Merci

//////////////////////////////////////// ///////////// Bonjour Stargazer712,

Je comprends vos commentaires jusqu'à ce qu'ils atteignent la méthode d'implémentation.

Supposons que nous avons les points suivants:

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

Vous avez dit que nous devons ajouter un nouveau point au milieu de tous les deux.

Ma question est ce que l'ordre du nouveau point est?

permettent d'utiliser utiliser cette annotation (A1 + A3)/2 == A12

nouveaux points maintenant générés sont

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

Où dois-je insérer ces points dans la liste initiale?

Le contour sur lequel je travaille est extrait de l'image binaire. Le contour généré est en forme de zigzag. Après avoir appliqué cette méthode lisse, la forme ne s'améliore pas trop. Je pense que la raison principale est que les voisins sont proches les uns des autres et rendent l'interpolation pas très utile.

Merci

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

Répondre

11

Je pense que ce que vous essayez de faire est de créer une courbe lisse interpolant les points. Pour ce faire, vous devez comprendre ce qui suit à propos des courbes de Bézier:

Disons que nous avons deux courbes avec les points A1, A2, A3, A4 et B1, B2, B3 et B4.

Si les deux courbes se terminent sur le même point, et si le dernier point de contrôle du premier est colinéaire avec le premier point de contrôle du suivant, alors les courbes seront lisses.Ainsi, dans notre exemple, si:

  • A4 == B1
  • A3, A4 et B2 sont colinéaires (même en disant A3, B1, B2 sont colinéaires)

Ensuite, les courbes seront être lisse. Pour prendre une liste arbitraire de points et faire une courbe régulière, nous devons forcer ces deux conditions à être vraies.

Pour ce faire, permet de dire que nous commençons par un ensemble de points:

Initial Points

Pour forcer les conditions ci-dessus, permet d'ajouter quelques points supplémentaires. Nous placerons un nouveau point au milieu de tous les deux comme indiqué:

With meta points

Nous pouvons maintenant tracer des courbes de Bézier entre les points 0-3, 3-6, 6-9, etc. et nous pouvons être sûrs qu'il formera une courbe lisse:

Curve drawn

Hope this helps!

EDIT: Voici un simple programme python qui implémente exactement ce qui a été montré ci-dessus (et je veux dire exactement). Python et PIL doivent être installés:

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") 

La ligne suivra le modèle des points. Si votre résultat est zigzagué, c'est parce que c'est à ça que ressemblaient les lignes.

+0

Bonjour Stargazer712, J'ai posté de nouvelles questions basées sur vos commentaires. s'il vous plaît voir le poste sous ma question initiale. merci – q0987

+0

@ q0987 - Le programme pour dessiner une courbe de Bézier est extrêmement simple. J'espère qu'un exemple répond à toutes les questions que vous pourriez avoir. – riwalk

+0

Merci beaucoup pour votre aide. Votre style de codage semble parfait :) – q0987