2009-12-09 14 views
6

Tôi đang thử triển khai vòng xoay bi xoay/bi xoay nhưng tôi gặp sự cố với vòng xoay trung tâm . Tôi muốn trung tâm trở thành trung tâm của màn hình của tôi cho dù thế nào đi chăng nữa.Làm thế nào để xoay về trung tâm của màn hình bằng cách sử dụng quaternions trong opengl?

Hãy để tôi giải thích những gì tôi đã làm cho đến thời điểm này.

Tôi đã tạo một quaterion (trục quay: vector_start x vector_end, góc: vector_start * vector_end)

Từ đó quaternion tôi đã tạo ra một ma trận xoay để sử dụng nó với glMultMatrixf (ma trận) và có được vòng quay mong muốn.

Vấn đề là trong khi mô hình của tôi dường như xoay vòng cung vì nó luôn xoay quanh nguồn gốc địa phương của nó. Làm thế nào tôi có thể làm cho nó xoay quanh tâm của màn hình của tôi bất kể nguồn gốc địa phương của nó nằm ở đâu?

Tôi giả sử một giải pháp cho vấn đề đó có thể là dịch toàn bộ trục quay ở giữa màn hình và sau đó áp dụng vòng xoay nhưng điều này có thể? Tôi có bỏ sót điều gì ở đây không?

Trả lời

1

Bạn sẽ có thể giải quyết vấn đề này bằng cách áp dụng các ma trận xoay vòng và dịch theo đúng thứ tự. Trong mã của bạn, bạn có thể dịch ngược lại nguồn gốc T (-pos_x, -pos_y, -pos_z), áp dụng vòng quay của bạn, và dịch sang trung tâm đối tượng một lần nữa T (pos_x, pos_y, pos_z). Điều này sẽ làm việc nói chung, độc lập với cách ma trận xoay của bạn được xây dựng.

+0

Có nhưng khi tôi áp dụng glMultMatrixf() không opengl quay mô hình xung quanh nguồn gốc địa phương của nó? Vì vậy, nếu tôi dịch sang nguồn gốc xoay (không phải bằng cách sử dụng glRotatef() nhưng glMultMatrix()) và sau đó dịch ngược lại mô hình của tôi sẽ được quay lại xung quanh nguồn gốc của nó và không phải là nguồn gốc của nó là trung tâm của màn hình chẳng hạn. –

+0

Dịch với glTranslatef(), sau đó nhân với ma trận xoay của bạn glMultMatrix(), và dịch ngược lại bằng glTranslatef(). Điều này trái ngược với việc chỉ gọi glMultMatrix(). Điều đó không hiệu quả? – catchmeifyoutry

+0

Không, nó không hoạt động. Những gì nó làm là nó quay mô hình như đã nói từ ma trận xoay được áp dụng bởi glMultMatrixf nhưng xung quanh nguồn gốc địa phương của nó. Tôi đã cố gắng để chuyển đổi quaternion xoay để góc Euler và sau đó áp dụng glRotatef (Yaw, 0., 0., 1.); glRotatef (Pich, 0., 1., 0.); glRotatef (Cuộn, 1., 0., 0.); thay vì áp dụng trực tiếp glMultMatrixf() nhưng sau đó trong khi xoay vòng là về trung tâm của màn hình, nó không liên quan gì đến vòng xoay vòng cung ! –

0

Dưới đây là một số mã tôi đã viết cách đây một lúc cho trình xem khởi chạy tên lửa 3 giai đoạn. Tôi nhận được hầu hết các thông tin từ http://www.euclideanspace.com/maths/geometry/rotations

Lưu ý: yaw, pitch and roll có thể thay đổi cho bạn dựa trên cách bạn thiết lập hệ thống

 // Assuming the angles are in radians. 
      double p = curPitch * Math.PI/180.0/2.0; 
      double y = curYaw * Math.PI/180.0/2.0; 
      double r = curRoll * Math.PI/180.0/2.0; 

      double sinp = Math.sin(p); 
      double siny = Math.sin(y); 
      double sinr = Math.sin(r); 
      double cosp = Math.cos(p); 
      double cosy = Math.cos(y); 
      double cosr = Math.cos(r); 

      Vector3 axis = new Vector3(); 

      //here's the important part: how you get your quaternion vector! 
      axis.x = sinr * cosp * cosy - cosr * sinp * siny; 
      axis.y = cosr * sinp * cosy + sinr * cosp * siny; 
      axis.z = cosr * cosp * siny - sinr * sinp * cosy; 

      //now normalize the vector in case we want to use it again later 
      axis = Vector3.normalizeVector(axis); 

      orientation[1] = axis.x; 
      orientation[2] = axis.y; 
      orientation[3] = axis.z; 

      //w is omega: the angle to rotate about the quaternion 
      double w = cosr * cosp * cosy + sinr * sinp * siny; 

      w = Math.acos(w) * 2.0; 

      orientation[0] = w; 

      gl.glPushMatrix(); 

       //translate object first, then rotate it. 
       gl.glTranslated(curDisplacement[0] + saveDisplacement[0], -curDisplacement[1] + saveDisplacement[2], curDisplacement[2] + saveDisplacement[1]); 

       //this order might be messed up because I screwed up my coordinate system, but the idea is still there 
       gl.glRotated(orientation[0]*180/Math.PI, orientation[2]*180/Math.PI, orientation[3]*180/Math.PI, orientation[1]*180/Math.PI); 

      //place your objects 
      gl.glPopMatrix(); 

Hope this helps phối hợp của bạn!