2010-08-18 18 views
9

Ho letto alcuni tutorial per la curva di Bezier come questa http://www.codeproject.com/KB/recipes/BezirCurves.aspx.Domanda sull'implementazione di Bezier Curves?

L'idea di base per creare una curva di Bézier è utilizzare alcuni punti di controllo e prendere una decisione su quanti nuovi punti devono essere creati. E poi interpola questi nuovi punti.

ecco la domanda:

Si supponga che ho 1000 punti e vorrei interpolare 2000 punti di più. Il numero di punti di controllo che voglio usare è 5. Il parametro t è nell'intervallo [0, 1].

Punti di consegna P0, P1, P2, P3, P4, P5, P6, ... P1000. Posso usare P0-P4 per generare nuovi punti, quindi quali sono i prossimi? usa P5-P9 per generare nuovi punti ??? Vedo subito che c'è una trasformazione improvvisa tra P4 e P5.

Come posso risolvere questo problema?

Grazie

//////////////////////////////////////// ///////////// Ciao Stargazer712,

Capisco i tuoi commenti fino a quando non raggiunge il metodo di implementazione.

Supponiamo di avere i seguenti punti:

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

Hai detto che abbiamo bisogno di aggiungere un nuovo punto a metà di ogni altra coppia.

La mia domanda è quale è l'ordine del nuovo punto?

uso Let utilizzare questa annotazione (A1 + A3)/2 == A12

nuovi punti Ora generati sono

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

Dove devo inserire i punti nella lista originale?

Il contorno su cui sto lavorando viene estratto dall'immagine binaria. Il contorno generato è a forma di zigzag. Dopo aver applicato questo metodo morbido, la forma non migliora troppo. Penso che la ragione principale sia che i vicini sono vicini e che l'interpolazione non è così utile.

Grazie

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

risposta

11

Penso che quello che stai cercando di fare è creare una curva uniforme interpolando i punti. Per fare questo, è necessario comprendere quanto segue sulle curve di Bezier:

Supponiamo di avere due curve con i punti A1, A2, A3, A4 e B1, B2, B3 e B4.

Se le due curve terminano sullo stesso punto e se l'ultimo punto di controllo del primo è colineare con il primo punto di controllo del successivo, le curve saranno lisce.Quindi, nel nostro esempio, se:

  • A4 == B1
  • A3, A4 e B2 sono collineare (equivale a dire A3, B1, B2 sono collineare)

Poi le curve saranno essere liscio.

Per prendere una lista arbitraria di punti e fare una curva regolare, dobbiamo forzare queste due condizioni ad essere vere.

A tale scopo, consente di dire che si comincia con una serie di punti:

Initial Points

Per forzare le condizioni di cui sopra, aggiungiamo alcuni punti extra. Ti posto un nuovo punto al punto medio di ogni altra coppia come mostrato:

With meta points

Possiamo ora disegnare curve di Bezier tra i punti 0-3, 3-6, 6-9, ecc , e possiamo essere sicuri che si formerà una curva regolare:

Curve drawn

Spero che questo aiuti!

EDIT: Ecco un semplice programma python che implementa esattamente ciò che è stato mostrato sopra (e intendo esattamente). È necessario installare python e 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") 

La linea seguirà lo schema dei punti. Se il risultato è a zig-zag, è perché è così che sembrano le linee.

+0

Ciao Stargazer712, Ho pubblicato nuove domande in base ai commenti. per favore vedi il post sotto la mia domanda originale. grazie – q0987

+0

@ q0987 - Il programma per disegnare una curva di Bézier è estremamente semplice. Spero che un esempio risponda a qualsiasi domanda tu possa avere. – riwalk

+0

Grazie mille per i tuoi grandiosi aiuti. Il tuo stile di codifica sembra perfetto :) – q0987