2011-02-23 33 views
5

Vì vậy, tôi đang chơi xung quanh với OpenGL và cố gắng tìm ra cách vẽ một số hình dạng thú vị.OpenGL Tube Dọc theo đường dẫn

Ngay bây giờ, tôi đang làm việc trên một ống. Tôi có thể rút ra một ống thẳng chỉ tốt với:

void tube(GLfloat radius, GLfloat segment_length) { 
    glPolygonMode(GL_BACK, GL_NONE); 
    glPolygonMode(GL_FRONT, GL_FILL); 

    glPushMatrix(); { 
     GLfloat z1 = 0.0; 
     GLfloat z2 = segment_length; 

     GLfloat y_offset = 0.0; 
     GLfloat y_change = 0.00; 

     int i = 0; 
     int j = 0; 
     for (j = 0; j < 20; j++) { 
      glPushMatrix(); { 
       glBegin(GL_TRIANGLE_STRIP); { 
        for (i = 360; i >= 0; i--) { 
         GLfloat theta = i * pi/180; 
         GLfloat x = radius * cos(theta); 
         GLfloat y = radius * sin(theta) + y_offset; 

         glVertex3f(x, y, z1); 
         glVertex3f(x, y, z2); 
        } 
       } glEnd(); 
      } glPopMatrix(); 

      // attach the front of the next segment to the back of the previous 
      z1 = z2; 
      z2 += segment_length; 

      // make some other adjustments 
      y_offset += y_change; 
     } 
    } glPopMatrix(); 
} 

Tuy nhiên, tôi đã không tìm ra cách để làm cho ống theo bất kỳ con đường được xác định trước như một vòng xoáy, hoặc thậm chí một dòng đơn giản. Nếu bạn thay đổi y_change thành một cái gì đó như 0,01, nó sẽ vẽ từng phân đoạn ống bù thêm 0,01 theo hướng y. Điều đó thật tuyệt, nhưng làm thế nào tôi có thể làm cho mỗi phân đoạn theo hướng đó? Nói cách khác, ngay bây giờ, mỗi đoạn được vẽ sao cho tất cả chúng đều hướng về cùng một hướng, và hướng không phải là hướng của ống (vì với y_change = 0,01, hướng hơi "lên").

Tôi không chắc chắn cách tiếp tục. Tôi đã chơi với vectơ bằng cách lấy véc-tơ giữa đoạn trước và đoạn hiện tại, nhưng tôi không thực sự chắc chắn phải làm gì với nó.

+1

bạn đã xem xét (đối với một ví dụ) Sách của Red dụ xuyến? http://www.opengl.org/resources/code/samples/redbook/torus.c –

Trả lời

17

Ý tưởng được gọi là đùn được kiểm soát đường dẫn, tức là bạn có hình dạng n chiều cơ bản và mở rộng dọc theo đường cong n + 1 chiều. Tôi có thể đọc được khuôn mặt của bạn: "Huh, anh ta nói gì vậy?"

Vì vậy, đây là một phác thảo thô. Trước tiên, bạn cần một hàm ánh xạ một giá trị, thường được gọi là t, đến một đường cong liên tục, trơn tru trong không gian. Ví dụ một vít:

path(t): R → R³, t ↦ (a·sin(k·t), b·cos(k·t), c·t) 

Ý tưởng là, để tìm một cơ sở địa phương phối hợp để xác định vị trí đỉnh của bạn liên quan đến con đường đó - nó có ý nghĩa, đó là một trong những tọa độ thẳng song song với con đường, vì vậy bạn muốn tìm nó tiếp tuyến. Này được thực hiện bằng cách tìm độ dốc của nó:

tangent(t): R → R³, t ↦ (k·a·cos(k·t), -k·b·sin(k·t), c) = d/dt path(t) 

Vì vậy, đây là vector cơ sở địa phương đó là chỉ dọc theo đường cong, với nguồn gốc của hệ toạ độ địa phương tại thời điểm t của đường cong.

Nhưng chúng tôi cần hai vectơ khác, để tạo thành một cơ sở 3d đầy đủ. Nó thường là một lựa chọn tốt để có điểm cơ sở thứ hai vuông góc với độ cong, mà bạn nhận được bằng cách tìm các curl của ốp:

normal(t): R → R³, t ↦ (-k²·a·sin(k·t), -k²·b·cos(k·t), 0) = d/dt tangent(t) = d²/dt² path(t) 

Điều này được gọi là bình thường.

Vectơ cơ sở thối có thể thu được, lấy sản phẩm thập phân của bình thường và tiếp tuyến, cho năng suất nhị phân. Tôi sẽ cho bạn thấy rằng đó là một bài tập.

Bây giờ để extrude một hình dạng dọc theo đường cong, bạn đã chia đường dẫn thành các phân đoạn, chỉ cần bằng cách lặp lại t trên một phạm vi được chọn, cung cấp cho bạn nguồn gốc địa phương. Các điểm của hình dạng ép đùn của bạn có liên quan đến đường dẫn gốc (t) này. Hãy nói rằng hình dạng của bạn bao gồm các điểm P_n trong mặt phẳng x-y thì:

for t in [k..l]: 
    for p in P_n: 
     yield_vertex(path(t).x + binormal(t).x * p.x, 
         path(t).y + normal(t).y * p.y, 
         path(t).z) 

Tôi sẽ để lại nó cho bạn, tìm ra cách để thích ứng này để OpenGL, sau khi tất cả các bạn nên học một cái gì đó bằng cách nghĩ về nó. Nếu bạn không thể giải quyết nó cho đến ngày mai, tôi sẽ sẵn sàng cung cấp cho bạn các giải pháp, nhưng nó thường vui hơn tìm ra những thứ bằng cách của riêng bạn.

+1

+1: Câu trả lời xuất sắc. Nếu bạn quan tâm đến một hàm tuyến tính mảnh, bạn có thể tìm tiếp tuyến là giá trị trung bình của v (n) (vectơ từ điểm cuối cùng đến điểm cuối) và v (n + 1) (vectơ từ điểm này sang trang kế tiếp). –

+0

tuyệt vời, cảm ơn câu trả lời này. Tôi sẽ dành thời gian để làm việc này. Tôi sẽ cho bạn biết những gì tiến bộ tôi thực hiện (mặc dù trường học và công việc có thể tiêu thụ một số thời gian giải trí của tôi mà tôi dành cho việc này). – gregghz

+0

vâng, tôi sợ rằng kỹ năng toán học của tôi không phải là điều này (một phần của vấn đề có thể là tôi không hoàn toàn hiểu được ký hiệu của bạn). Tôi dường như không thể dịch nó sang OpenGL, có vẻ như không quan trọng tôi làm gì, các đoạn ống luôn hướng về một hướng. – gregghz

Các vấn đề liên quan