2010-08-18 25 views
9

Tôi đã đọc một số hướng dẫn cho đường cong bezier như thế này http://www.codeproject.com/KB/recipes/BezirCurves.aspx.Câu hỏi về việc thực hiện Bezier Curves?

Ý tưởng cơ bản để tạo đường cong bezier là sử dụng một số điểm kiểm soát và đưa ra quyết định cần tạo bao nhiêu điểm mới. Và sau đó nội suy những điểm mới.

Đây là câu hỏi:

Giả sử tôi có 1000 điểm và tôi muốn nội suy thêm 2000 điểm. Số lượng điểm kiểm soát tôi muốn sử dụng là 5. Tham số t nằm trong khoảng [0, 1].

Givens điểm P0, P1, P2, P3, P4, P5, P6, ... P1000. Tôi có thể sử dụng P0-P4 để tạo điểm mới, sau đó tiếp theo là gì? sử dụng P5-P9 để tạo điểm mới ??? Tôi ngay lập tức có thể thấy có sự biến đổi đột ngột giữa P4 và P5.

Tôi làm cách nào để giải quyết vấn đề này?

Cảm ơn bạn

////////////////// ///////////// Xin chào Stargazer712,

Tôi hiểu các nhận xét của bạn cho đến khi nó đạt đến phương pháp triển khai.

Giả sử chúng ta có những điểm sau đây:

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

Bạn nói rằng chúng ta cần thêm một điểm mới tại trung điểm của mỗi cặp khác.

Câu hỏi của tôi là thứ tự của điểm mới là gì?

Hãy sử dụng sử dụng chú thích này (A1 + A3)/2 == A12

Bây giờ tạo ra điểm mới là

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

tôi nên chèn những điểm đâu vào danh sách ban đầu?

Đường bao mà tôi đang làm việc được trích xuất từ ​​hình ảnh nhị phân. Đường bao tạo ra là hình dạng zig-zag. Sau khi tôi áp dụng phương pháp trơn tru này, hình dạng không cải thiện quá nhiều. Tôi nghĩ lý do chính là những người hàng xóm ở gần nhau và làm cho nội suy không hữu ích.

Cảm ơn bạn

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

Trả lời

11

Tôi nghĩ rằng những gì bạn đang cố gắng làm là tạo một đường cong trơn tru nội suy các điểm. Để thực hiện điều này, bạn cần phải hiểu những điều sau đây về đường cong Bezier:

Giả sử chúng tôi có hai đường cong với điểm A1, A2, A3, A4 và B1, B2, B3 và B4.

Nếu hai đường cong kết thúc trên cùng một điểm và nếu điểm kiểm soát cuối cùng của điểm đầu tiên là colinear với điểm điều khiển đầu tiên của điểm tiếp theo, thì đường cong sẽ trơn tru.Vì vậy, trong ví dụ của chúng tôi, nếu:

  • A4 == B1
  • A3, A4, và B2 là colinear (giống như nói A3, B1, B2 là colinear)

Sau đó các đường cong sẽ được mịn màng.

Để lấy một danh sách tùy ý các điểm và tạo một đường cong trơn tru, chúng ta cần phải buộc hai điều kiện này trở thành sự thật.

Để làm điều này, cho phép nói rằng chúng ta bắt đầu với một tập hợp các điểm:

Initial Points

Để buộc các điều kiện trên, cho phép thêm một số điểm bổ sung. Chúng tôi sẽ đặt một điểm mới tại trung điểm của mỗi cặp khác như:

With meta points

Bây giờ chúng ta có thể vẽ đường cong bezier giữa các điểm 0-3, 3-6, 6-9, vv , và chúng tôi có thể chắc chắn rằng nó sẽ tạo thành một đường cong mịn:

Curve drawn

Hope this helps!

EDIT: Đây là chương trình python đơn giản triển khai chính xác những gì được hiển thị ở trên (và ý tôi là chính xác). Bạn cần cài đặt python và 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") 

Đường sẽ theo mẫu của điểm. Nếu kết quả của bạn là zig-zagged, đó là bởi vì đó là những gì các dòng trông như thế nào.

+0

Xin chào Stargazer712, Tôi đã đăng câu hỏi mới dựa trên nhận xét của bạn. xin vui lòng xem bài viết dưới câu hỏi ban đầu của tôi. cảm ơn bạn – q0987

+0

@ q0987 - Chương trình vẽ đường cong bezier cực kỳ đơn giản. Tôi hy vọng một ví dụ trả lời bất kỳ câu hỏi nào bạn có thể có. – riwalk

+0

Cảm ơn bạn rất nhiều vì sự giúp đỡ tuyệt vời của bạn. Kiểu mã hóa của bạn trông hoàn hảo :) – q0987