2010-07-08 30 views
9

Khi tôi có QUAD ở một vị trí nhất định, làm thế nào tôi có thể xoay nó theo cách sao cho điểm thông thường của nó hướng tới một điểm nhất định? Hãy tưởng tượng các khối màu chỉ là quads hình chữ nhật, sau đó hình ảnh này cho thấy một chút những gì tôi có ý nghĩa. Các tứ giác đều được định hướng theo cách mà chúng hướng tới tâm của quả cầu.C++/openGL: Xoay một QUAD về phía điểm bằng cách sử dụng quaternions

alt text http://emrahgunduz.com/wp-content/uploads/2009/01/material_id_gui-600x364.jpg

Có lẽ hình ảnh thứ hai này cho thấy hơn một chút những gì tôi đang cố gắng để làm: alt text http://img689.imageshack.us/img689/3130/screenshot20100708at555.png

Tôi đang sử dụng OpenGL/C++ (và lib Eigen). Và tôi có mã này để vẽ một quad đơn giản:

#include "ofMain.h" 
#include "Quad.h" 
Quad::Quad(Vector3f oPosition):position(oPosition) { 
} 

void Quad::update() { 
} 

void Quad::draw() { 
    float size = 1.3; 
    glColor3f(1.0f, 0.0f, 0.6f); 
    glPushMatrix(); 
     glTranslatef(position.x(), position.y(), position.z()); 
     glScalef(size, size,size); 
     glBegin(GL_QUADS); 
      glVertex3f(0,0,0); 
      glVertex3f(1,0,0); 
      glVertex3f(1,1,0); 
      glVertex3f(0,1,0); 
     glEnd(); 
    glPopMatrix(); 
} 

Cập nhật 17-07 Thưa quý độc giả,

Chỉ cần có một chút xa hơn với xoay Quads. Tôi đang định vị một vài quads một cách ngẫu nhiên và sau đó tôi xoay chúng hướng tới một look_at vector3f sử dụng mã này sử dụng các mô tả từ các câu trả lời dưới đây:

void Quad::draw() { 
    float size = 0.5; 
    glColor3f(1.0f, 0.0f, 0.6f); 
    glPushMatrix(); 
     Vector3f center = look_at - position; 
     Vector3f center_norm = center.normalized(); 
     float r_angle = acos(center_norm.dot(normal)); 
     Vector3f axis = normal.normalized().cross(center_norm); 

     glPointSize(8); 
     glLineWidth(4.0f); 

     // draw the center point 
     glColor3f(1.0f, 0.0f, 0.0f); 
     glBegin(GL_POINTS); 
      glVertex3fv(look_at.data()); 
     glEnd(); 

     // draw the quad 
     glColor4f(0.0f, 0.0f, 0.0f, 0.85f); 
     glTranslatef(position.x(), position.y(), position.z()); 
     glRotatef(r_angle * RAD_TO_DEG, axis.x(), axis.y(), axis.z()); 
     glScalef(size, size,size); 
     glBegin(GL_QUADS); 
      glVertex3f(-0.5,-0.5,0); 
      glVertex3f(0.5,-0.5,0); 
      glVertex3f(0.5,0.5,0); 
      glVertex3f(-0.5,0.5,0); 
     glEnd(); 

    glPopMatrix(); 
} 

Kết quả trông như thế này: alt text http://img688.imageshack.us/img688/711/3drotatedquads.png

Như bạn có thể thấy tôi gần như ở đó, mặc dù vòng quay của quads vẫn còn hơi "lạ". Tôi bạn nhìn thấy hình ảnh dưới đây với các quads màu bạn rõ ràng thấy sự khác biệt trong luân chuyển. Làm thế nào tôi có thể xoay quad theo cách như vậy tôi nhận được kết quả tương tự như quả cầu màu dưới đây?

+0

+1: Vì tôi yêu hình ảnh 3D :) – ereOn

+0

Các liên kết hình ảnh này đều bị hỏng. –

Trả lời

1

xoay trục = bình thường hóa (tích vectơ (currentNormal, desiredNormal))

Rotation angle = acos (dotproduct (bình thường (currentNormal), bình thường (desiredNormal)).

Bạn có thể xây dựng một trong hai ma trận xoay hoặc quaternion từ trục và góc. công thức chính xác có thể được tìm thấy trong bất kỳ tài nguyên về quaternion.

bạn có thể cần phải lật góc hoặc trục tùy thuộc vào việc bạn xoay bình thường xung quanh cơ sở hoặc xung quanh nó của nó tip.

Ngoài ra THIS tài nguyên dường như có đủ thông tin về quaternions, luân chuyển, và không gian 3d nói chung.

+0

Hi SigTerm, nhưng làm cách nào để giải quyết vấn đề này khi tôi không biết hiện tại của mình? Tôi chỉ có mã tôi dán (lớp 'Quad'). – pollux

+1

Đối với một quad abcd bình thường có thể được tìm thấy bằng cách sử dụng sản phẩm chéo = normalize (chéo (c-a, d-b)) hoặc chuẩn hóa (Crossproduct (b-a, c-a)). Bất kỳ hai vectơ không song song nào từ quad có thể được sử dụng để làm vuông góc. Trong ví dụ bình thường của bạn là (0, 0, 1) hoặc (0, 0, -1). (phụ thuộc vào việc quads sử dụng cùng một thứ tự quanh co, một mặt hoặc hai mặt, vv). – SigTerm

+0

SigTerm, ý bạn là gì khi xoay quanh 'cơ sở' hoặc 'mẹo'? Điều này có thể gây ra kết quả tôi có ngay bây giờ (xem quads đen ở trên) – pollux

0

Nếu "tại một vị trí nhất định" có nghĩa là bạn biết hiện tại bình thường của bạn, hơn đây là điều:

  1. Dot sản phẩm của một cũ và mới bình thường được một cosin của một góc giữa chúng.
  2. Sản phẩm chéo của họ là trục mà bạn nên thực hiện xoay mong muốn
  3. Xây dựng quaternion xoay từ trục và góc đã cho là tài liệu và tính năng cơ bản.
  4. Xoay quad chính nó là khó khăn và phụ thuộc vào cách chính xác những gì bạn muốn nó được luân chuyển.