2010-08-18 24 views
9

He leído algunos tutoriales para la curva bezier como este http://www.codeproject.com/KB/recipes/BezirCurves.aspx.Pregunta sobre la implementación de Bezier Curves?

La idea básica para crear una curva bezier es usar algunos puntos de control y tomar decisiones sobre cuántos puntos nuevos se necesitan crear. Y luego interpola esos nuevos puntos.

aquí está la pregunta:

Supongamos que tengo 1000 puntos y me gustaría para interpolar 2000 puntos más. El número de puntos de control que quiero usar es 5. El parámetro t está en el rango de [0, 1].

Givens puntos P0, P1, P2, P3, P4, P5, P6, ... P1000. Puedo usar P0-P4 para generar nuevos puntos, ¿qué sigue? usa P5-P9 para generar nuevos puntos ??? De inmediato puedo ver que hay una transformación repentina entre P4 y P5.

¿Cómo puedo resolver este problema?

Gracias

//////////////////////////////////////// ///////////// Hola Stargazer712,

Entiendo sus comentarios hasta que llegue al método de implementación.

Asumamos que tenemos los siguientes puntos:

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

Usted ha dicho que tenemos que añadir un nuevo punto en el punto medio de cada otro par.

Mi pregunta es cuál es el orden del nuevo punto?

usar le permiten utilizar esta anotación (A1 + A3)/2 == A12

nuevos puntos generados Ahora son

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

¿Dónde debería introducir esos puntos en la lista original?

El contorno en el que estoy trabajando se extrae de una imagen binaria. El contorno generado tiene forma de zig-zag. Después de aplicar este método suave, su forma no mejora demasiado. Creo que la razón principal es que los vecinos están cerca unos de otros y hacen que la interpolación no sea tan útil.

Gracias

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

Respuesta

11

Creo que lo que estás tratando de hacer es crear una curva suave interpolando los puntos. Para hacerlo, debe comprender lo siguiente acerca de las curvas de Bezier:

Supongamos que tenemos dos curvas con los puntos A1, A2, A3, A4 y B1, B2, B3 y B4.

Si las dos curvas terminan en el mismo punto, y si el último punto de control del primero es colineal con el primer punto de control del siguiente, las curvas serán suaves.Así, en nuestro ejemplo, si:

  • A4 == B1
  • A3, A4 y B2 son colineales (mismo que decir A3, B1, B2 son colineales)

Entonces las curvas se ser suave.

Para tomar una lista arbitraria de puntos y hacer una curva suave, debemos forzar que estas dos condiciones sean verdaderas.

Para hacer esto, supongamos que partimos de un conjunto de puntos:

Initial Points

Para forzar las condiciones anteriores, vamos a añadir algunos puntos extra. Nosotros colocaremos un nuevo punto en el punto medio de cada otro par como se muestra:

With meta points

Ahora podemos dibujar curvas de Bézier entre los puntos 0-3, 3-6, 6-9, etc. y podemos estar seguros de que va a formar una curva suave:

Curve drawn

Espero que esto ayude!

EDITAR: Aquí hay un programa simple de Python que implementa exactamente lo que se mostró arriba (y me refiero exactamente). Necesita tener python y PIL instalado:

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 línea seguirá el patrón de los puntos. Si tu resultado está en zigzag, es porque así son las líneas.

+0

Hola Stargazer712, He publicado nuevas preguntas basadas en sus comentarios. por favor mira la publicación debajo de mi pregunta original. gracias – q0987

+0

@ q0987 - El programa para dibujar una curva bezier es extremadamente simple. Espero que un ejemplo responda a cualquier pregunta que pueda tener. – riwalk

+0

Muchas gracias por sus excelentes ayuda. Tu estilo de codificación se ve perfecto :) – q0987