2010-08-09 40 views
12

Làm thế nào tôi có thể giới hạn hiệu quả độ cao của máy ảnh khi tôi chỉ có quaternion camera? Tôi có phải chuyển đổi sang góc độ euler và sau đó trở lại quaternion hoặc là có cách nào khác?Giới hạn độ cao của máy ảnh

+0

Wert, tôi đã cố gắng suy nghĩ về một câu trả lời tốt trong vài giờ qua bây giờ ... người đàn ông, nó được năm kể từ khi tôi xử lý quaternions ... Tôi bây giờ có khói ra khỏi tai của tôi ... Tôi bỏ ... ;-) – ysap

Trả lời

0

quaternion camera xoay có thể được định nghĩa là:

vector A = [x, y, z] 
Q.x = A.x * sin(theta/2) 
Q.y = A.y * sin(theta/2) 
Q.z = A.z * sin(theta/2) 
Q.w = cos(theta/2) 

đâu A là vị trí và theta là góc bạn muốn xoay máy ảnh (điều chỉnh sân).

Vì vậy, nếu bạn có quaternion có sẵn, bạn có thể giới hạn góc sân bằng cách xác minh mỗi lần nếu góc quay cộng/trừ góc thực tế là ok.

Tôi nghĩ rằng bạn có thể tránh được chuyển đổi nếu bạn thiết lập giới hạn của bạn như

+cos(supLim/2) < (Q.w + P.w) < -cos(infLim/2) 

Như cosin là một hàm liên tục này là nghĩa vụ phải làm việc.

Nếu bạn có thể đăng mã bạn đang sử dụng, có thể chúng tôi có thể giúp thêm một chút.

+0

Hmm .. không phải là một trục quay? Làm cách nào tôi có thể đặt quaternion thành giới hạn độ cao nếu vượt quá giới hạn? – Wert

+0

A chắc chắn là trục là một vectơ đơn vị. Ngay cả khi "vị trí" là lỗi đánh máy, câu trả lời sẽ chỉ hoạt động nếu Q chỉ là xoay vòng, chứ không phải xoay tổng số camera C. Chúng tôi đang cố gắng trích xuất Q từ C. – SuperElectric

1

Độ cao chỉ là một thành phần của vòng quay đầy đủ, vì vậy nếu bạn muốn suy nghĩ về vòng quay của mình như thế, bạn nên lưu trữ riêng biệt hơn, có thể sử dụng góc Euler.

Chỉ cần chuyển sang góc Euler và ngược lại khi bạn cần giới hạn chuyển động có thể không hoạt động tốt, vì bạn cần nhớ khung cuối cùng (nếu có) để xem bạn đã vượt quá giới hạn chưa, và những gì hướng.

Như tôi thấy, điểm chính của quaternions là bạn không cần phải bận tâm với các giới hạn như thế. Tất cả mọi thứ chỉ hoạt động mà không có bất kỳ singularities. Tại sao chính xác bạn muốn giới hạn sân?

2

Nếu máy ảnh không bao giờ có bất kỳ cuộn nào (như phổ biến trong nhiều trò chơi, chẳng hạn như game bắn súng người đầu tiên), thì giải pháp rất đơn giản. Nếu có cuộn thì có thêm một bước nữa. Tôi sẽ bắt đầu với những gì cần làm nếu không có cuộn, và tổng quát hóa giải pháp để làm gì nếu có.

Cho qc là xoay camera. Cho qy một vòng quay với cùng một yaw như qc, nhưng với độ cao bằng không. Nếu không có cuộn, xoay máy ảnh là một vòng xoay yaw tiếp theo vòng xoay sân:

qc = qp * qy 

Chúng ta có thể khôi phục lại qp xoay sân như luân chuyển từ qy để qc:

qp = qc * qy^-1 

Bí quyết , sau đó, là xây dựng qy, vì vậy chúng ta có thể cắm nó vào phương trình trên để giải quyết cho qp. Cho vc là vector đơn vị chỉ ra khỏi ống kính của máy ảnh hoặc "vectơ tiến". Hãy để vy là cùng một vector, nhưng chiếu lên mặt phẳng nằm ngang và chuẩn hóa. Cuối cùng, hãy v0 là vectơ chuyển tiếp khi xoay camera qc là xoay vòng định danh. Xoay quay v0 thành vy là vòng quay quay. Góc có thể được đưa ra như:

yaw = asin(Norm(cross(v0, vy))) 

Vòng xoay yaw tương ứng là:

qy = { cos(yaw/2), up * sin(yaw/2) } 

đâu "lên" là vector đơn vị theo hướng lên, còn gọi là trục cho phép quay yaw. Cắm cái này vào qp = qy^-1 * qc ở trên để lấy qp quaternion.Cuối cùng, nhận góc sân từ qp là:

pitch = 2*asin(Dot(right, [qp[1], qp[2], qp[3]])) 

Trường hợp "đúng" là véc tơ đơn vị đi đúng hướng, còn gọi là trục quay vòng.

Như tôi đã nói, mọi thứ trở nên phức tạp hơn nếu máy ảnh cũng có cuộn, nhưng chiến lược chung là như nhau. Bạn xây dựng xoay camera như một sản phẩm của các thành phần xoay, sau đó cô lập thành phần bạn muốn (trong trường hợp này là pitch). Ví dụ, nếu chuỗi Euler bạn sử dụng để xác định "sân" là chuỗi yaw-sân-roll thông thường, bạn xác định qc như:

qc = qr * qp * qy 

Chúng ta có thể định nghĩa một qx biến là sân and roll quay kết hợp :

qx = qr * qp 

chúng tôi bây giờ có thể viết qc như:

qc = qx * qy 

chúng tôi đã biết làm thế nào để giải quyết cho qx theo hình thức này, bởi retracing các bước chúng tôi đã sử dụng ở trên để giải quyết cho qp. Sắp xếp lại định nghĩa cho qx, chúng tôi nhận được:

qp = qr^-1 * qx 

Chúng tôi chỉ giải quyết cho qx, vì vậy để giải quyết cho qp xoay sân, chúng tôi chỉ cần cuộn qr. Chúng ta có thể xây dựng nó bằng cách sử dụng các vectơ như chúng ta đã làm trước đó. Hãy vc là vector chuyển tiếp một lần nữa. Cuộn sẽ xoay quanh vectơ này. Hãy để vu là vector của máy ảnh (trong tọa độ thế giới), và để vu0 là máy ảnh của vector lên với cuộn không. Chúng ta có thể xây dựng vu0 bằng cách chiếu vector toàn cầu lên mặt phẳng vuông góc với vc, sau đó chuẩn hóa. Vòng quay cuộn qr sau đó là vòng quay từ vu0 đến vu. Trục quay này là vc vectơ về phía trước. Góc cuộn là

roll = asin(Dot(vc, cross(vu0, vu))) 

các quaternion tương ứng là:

qr = { cos(roll/2), forward * sin(roll/2) } 

đâu "chuyển tiếp" là trục quay cuộn.

0

Tôi có thể là một chút muộn để đảng, nhưng đây là cách tôi giải quyết nó:

 // "Up" = local vector -> rotation * Vector3.UnitY 
     // "Forward" = local vector -> rotation * Vector3.UnitZ 
     // "Right" = local vector -> rotation * Vector3.UnitX 

    public void Rotate(Vector3 axis, float angle) 
    { 
     if (LerpRotation) 
     { 
      RotationTarget *= Quaternion.FromAxisAngle(axis, angle); 
     } 
     else 
     { 
      Rotation *= Quaternion.FromAxisAngle(axis, angle); 
     } 
     //Locking the Pitch in 180° 
     float a = Vector3.CalculateAngle(Vector3.UnitY, Up); 
     float sign = Math.Sign(Forward.Y); 
     float delta = (float)Math.PI/2 - a; 
     if(delta < 0) 
      Rotation *= Quaternion.FromAxisAngle(Right, delta * sign); 
    } 
Các vấn đề liên quan