Làm thế nào để giải quyết vấn đề khóa gimbal bằng cách sử dụng các phép biến đổi ma trận tích lũy


12

Tôi đang đọc cuốn sách "Học lập trình đồ họa 3D hiện đại" trực tuyến của Jason L. McKesson

Đến bây giờ, tôi gặp vấn đề về khóa gimbal và cách giải quyết bằng cách sử dụng tứ phương.

Tuy nhiên ngay tại đây, tại trang Đệ tứ .

Một phần của vấn đề là chúng tôi đang cố gắng lưu trữ một định hướng như một chuỗi gồm 3 vòng quay trục tích lũy. Định hướng là định hướng, không phải xoay. Và định hướng chắc chắn không phải là một loạt các vòng quay. Vì vậy, chúng ta cần coi định hướng của con tàu là một định hướng, như một số lượng cụ thể.

Tôi đoán đây là điểm đầu tiên tôi bắt đầu bối rối, lý do là vì tôi không thấy sự khác biệt đáng kể giữa định hướng và xoay. Tôi cũng không hiểu tại sao một định hướng không thể được biểu diễn bằng một loạt các phép quay ...

Cũng thế:

Ý nghĩ đầu tiên hướng đến kết thúc này sẽ là giữ định hướng như một ma trận. Khi đến lúc phải sửa đổi hướng, chúng ta chỉ cần áp dụng một phép biến đổi cho ma trận này, lưu trữ kết quả làm hướng hiện tại mới.

Điều này có nghĩa là mọi ngáp, cao độ và cuộn được áp dụng cho hướng hiện tại sẽ liên quan đến hướng hiện tại đó. Đó chính xác là những gì chúng ta cần. Nếu người dùng áp dụng một cái ngáp tích cực, bạn muốn cái ngáp đó xoay chúng so với vị trí của chúng hiện tại, không liên quan đến một số hệ tọa độ cố định.

Khái niệm, tôi hiểu, tuy nhiên tôi không hiểu làm thế nào nếu tích lũy các phép biến đổi ma trận là một giải pháp cho vấn đề này, làm thế nào mã được đưa ra trong trang trước không chỉ như vậy.

Đây là mã:

void display()
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepth(1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glutil::MatrixStack currMatrix;
    currMatrix.Translate(glm::vec3(0.0f, 0.0f, -200.0f));
    currMatrix.RotateX(g_angles.fAngleX);
    DrawGimbal(currMatrix, GIMBAL_X_AXIS, glm::vec4(0.4f, 0.4f, 1.0f, 1.0f));
    currMatrix.RotateY(g_angles.fAngleY);
    DrawGimbal(currMatrix, GIMBAL_Y_AXIS, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f));
    currMatrix.RotateZ(g_angles.fAngleZ);
    DrawGimbal(currMatrix, GIMBAL_Z_AXIS, glm::vec4(1.0f, 0.3f, 0.3f, 1.0f));

    glUseProgram(theProgram);
    currMatrix.Scale(3.0, 3.0, 3.0);
    currMatrix.RotateX(-90);
    //Set the base color for this object.
    glUniform4f(baseColorUnif, 1.0, 1.0, 1.0, 1.0);
    glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(currMatrix.Top()));

    g_pObject->Render("tint");

    glUseProgram(0);

    glutSwapBuffers();
}

Theo hiểu biết của tôi, không phải những gì anh ta đang làm (sửa đổi ma trận trên ngăn xếp) được coi là ma trận tích lũy, vì tác giả đã kết hợp tất cả các phép biến đổi xoay vòng riêng lẻ thành một ma trận đang được lưu trữ trên đỉnh của ngăn xếp.

Sự hiểu biết của tôi về một ma trận là chúng được sử dụng để lấy một điểm có liên quan đến một điểm gốc (giả sử ... mô hình) và làm cho nó liên quan đến một nguồn gốc khác (máy ảnh). Tôi khá chắc chắn rằng đây là một định nghĩa an toàn, tuy nhiên tôi cảm thấy như thiếu một thứ gì đó đang cản trở tôi hiểu vấn đề khóa gimbal này.

Một điều không có ý nghĩa với tôi là: Nếu một ma trận xác định sự khác biệt tương đối giữa hai "không gian", thì làm thế nào để xoay quanh trục Y, giả sử, cuộn, không đặt điểm vào "không gian cuộn "sau đó có thể được chuyển đổi một lần nữa liên quan đến cuộn này ... Nói cách khác, không nên có bất kỳ biến đổi nào nữa cho đến thời điểm này liên quan đến" không gian cuộn "mới này và do đó không có vòng quay so với trước đó" không gian mô hình "gây ra khóa gimbal.

Đó là lý do tại sao khóa gimbal xảy ra phải không? Đó là bởi vì chúng ta đang xoay đối tượng xung quanh các trục X, Y và Z thay vì xoay đối tượng xung quanh nó, các trục tương đối nó. Hoặc là tôi sai?

Vì rõ ràng mã này tôi đã liên kết không phải là sự tích lũy của các phép biến đổi ma trận, bạn có thể vui lòng cho một ví dụ về giải pháp sử dụng phương pháp này.

Vì vậy, tóm lại:

  • Sự khác biệt giữa một vòng quay và một định hướng là gì?
  • Tại sao mã được liên kết trong không phải là một ví dụ về tích lũy các phép biến đổi ma trận?
  • Mục đích thực sự, cụ thể của ma trận là gì, nếu tôi có sai?
  • Làm thế nào một giải pháp cho vấn đề khóa gimbal có thể được thực hiện bằng cách sử dụng tích lũy các phép biến đổi ma trận?
  • Ngoài ra, như một phần thưởng: Tại sao các biến đổi sau khi xoay vẫn liên quan đến "không gian mô hình?"
  • Một phần thưởng khác: Tôi có sai trong giả định rằng sau khi chuyển đổi, các biến đổi tiếp theo sẽ xảy ra so với hiện tại không?

Ngoài ra, nếu không ngụ ý, tôi đang sử dụng OpenGL, GLSL, C ++ và GLM, vì vậy các ví dụ và giải thích về những điều này được đánh giá rất cao, nếu không cần thiết.

Càng nhiều chi tiết càng tốt!

Cảm ơn trước.

Câu trả lời:


11

Tôi không chắc chắn về một cách tốt để mở đầu điều này, ngoài việc tôi hy vọng nó sẽ liên kết với nhau tốt đẹp vào cuối. Điều đó nói rằng, hãy đi sâu vào:

Một phép quay và một hướng là khác nhau bởi vì cái trước mô tả một phép biến đổi và cái sau mô tả một trạng thái. Xoay là cách một đối tượng đi vào một hướng và một hướng là không gian xoay cục bộ của đối tượng . Điều này có thể liên quan trực tiếp đến cách hai cái được biểu diễn dưới dạng toán học: một ma trận lưu trữ các phép biến đổi từ không gian tọa độ này sang không gian tọa độ khác (bạn đã có chính xác) và một tứ phương mô tả trực tiếp một định hướng. Do đó, ma trận chỉ có thể mô tả cách đối tượng đi vào một hướng , thông qua một loạt các phép quay. Tuy nhiên, vấn đề với điều này là Khóa Gimbal.

Khóa Gimbal cho thấy sự khó khăn khi đưa một vật thể vào một hướng bằng cách sử dụng một loạt các phép quay. Sự cố xảy ra khi ít nhất hai trong số các trục xoay thẳng hàng:

Hình ảnh lịch sự của deepmesh3d.com
Trong hình bên trái ở trên, các trục màu xanh và màu cam thực hiện cùng một vòng quay! Đây là một vấn đề, bởi vì điều này có nghĩa là một trong ba mức độ tự do đã bị mất và các phép quay bổ sung từ thời điểm này có thể tạo ra kết quả bất ngờ. Sử dụng tứ phân giải quyết điều này bởi vì áp dụng một bậc bốn để chuyển đổi hướng của một đối tượng sẽ trực tiếp đưa đối tượng theo một hướng mới (đó là cách tốt nhất tôi có thể nói), thay vì phá vỡ sự chuyển đổi thành các thao tác cuộn, cao độ và ngáp.

Bây giờ, tôi thực sự hoài nghi về việc tích lũy ma trận là một giải pháp hoàn chỉnh cho vấn đề này, bởi vì ma trận tích lũy (do đó tích lũy các phép quay) là chính xác những gì có thể gây ra vấn đề Khóa Gimbal ngay từ đầu. Cách thích hợp để xử lý sự biến đổi bởi một bậc bốn là hoặc thực hiện phép nhân bậc bốn trên một điểm:

pTransformed = q * pAsQuaternion * qConjugate

hoặc bằng cách chuyển đổi bậc bốn thành ma trận và biến đổi điểm bằng ma trận đó.

Một vòng quay ma trận đơn giản (như ngáp 45 độ) sẽ luôn được xác định trong không gian toàn cầu. Nếu bạn muốn áp dụng phép biến đổi trong không gian cục bộ, bạn sẽ phải chuyển đổi phép biến đổi của mình thành không gian cục bộ đó. Nghe có vẻ lạ, vì vậy tôi sẽ giải thích. Đây là nơi tầm quan trọng của thứ tự xoay vòng xuất hiện. Tôi khuyên bạn nên lấy một cuốn sách ở đây để bạn có thể làm theo cùng với các biến đổi.

Bắt đầu với cuốn sách phẳng, bìa của nó hướng lên trần nhà, định hướng như thể bạn sắp mở nó và bắt đầu đọc. Bây giờ nghiêng mặt trước của cuốn sách lên 45 độ (bìa trước sẽ gần như đối diện với bạn):

glutil::MatrixStack bookMatrix;
bookMatrix.RotateX(45);

Bây giờ, giả sử bạn muốn điều chỉnh ngáp của cuốn sách 45 độ (Tôi nghĩ rằng tôi đang giả sử hệ thống tọa độ thuận tay phải, vì vậy điều này sẽ thay đổi hướng về bên trái) và bạn muốn áp dụng điều này cho địa phương của cuốn sách phối hợp không gian, để bìa sách vẫn sẽ đối mặt với bạn:

bookMatrix.RotateY(45);

Vấn đề là, vòng quay này xảy ra trong không gian tọa độ toàn cầu, vì vậy bìa sách sẽ kết thúc đối diện với vai phải của bạn. Để thay đổi tiêu đề này xảy ra trong không gian tọa độ cục bộ, bạn nên áp dụng nó trước!

glutil::MatrixStack bookMatrix;
bookMatrix.RotateY(45);
bookMatrix.RotateX(45);

Hãy thử nó! Bắt đầu cuốn sách hướng lên trần nhà một lần nữa. Thay đổi ngáp 45 độ, và sau đó nghiêng 45 độ dọc theo trục X toàn cầu (chạy từ trái sang phải). Đây là định hướng bạn mong đợi với độ cao 45 và ngáp 45 trong không gian địa phương của cuốn sách.

Điều đó có nghĩa là gì? Tất cả những gì nó thực sự đi xuống là thứ tự của các hoạt động quan trọng. Các phép biến đổi được thực hiện trước tiên trở thành phép biến đổi cục bộ trong bối cảnh các phép biến đổi được thực hiện sau đó. Nó trở nên rất nhiều để quấn đầu bạn, và đây là cách mà các bậc bốn cứu được rất nhiều rắc rối. Bỏ qua tất cả các công cụ phụ thuộc vào thứ tự.

Ưu điểm to lớn khác mà tứ phương cung cấp là chúng cho phép nội suy các định hướng. Cố gắng nội suy giữa các góc Euler là gần như không thể vì phụ thuộc thứ tự. Các tính chất toán học của bậc bốn cho phép nội suy tuyến tính hình cầu được xác định rõ giữa chúng.

Để kết thúc mọi thứ và giải quyết câu hỏi ban đầu của bạn: các phép biến đổi ma trận tích lũy thực sự sẽ không giải quyết được vấn đề khóa Gimbal, trừ khi các phép biến đổi được lựa chọn cẩn thận và áp dụng theo một thứ tự chính xác. Do đó, luôn luôn sử dụng bậc bốn và áp dụng bậc bốn cho các điểm bằng cách sử dụng phép nhân bậc bốn.

Hi vọng điêu nay co ich :)


4
chỉ để ghi lại, tứ phương vẫn có thể giới thiệu khóa gimbal nếu được mô tả qua các góc Euler; vì bạn sẽ thực hiện cùng một phép tính theo một cách khác (
tứ phương

1
@ concept3d - chúc mừng bạn đã đề cập đến điều này! Điều quan trọng là phải hiểu điều gì làm cho cơ chế gimbal dễ bị mất một mức độ tự do: nó giống như một khớp robot vốn mô tả một hệ phương trình quá hạn. Nếu bạn xây dựng cơ chế này với tứ phương, ma trận hoặc ma thuật, bạn vẫn kết thúc với sự mơ hồ - đó là hiểu nó và không sử dụng nó ở nơi đầu tiên đó là một giải pháp thực sự (trừ khi bạn được yêu cầu sử dụng nó cho mục đích kỹ thuật hoặc trình diễn) .
teodron

Các bậc bốn rất khó tưởng tượng, theo cách mà tôi luôn nghĩ về nó là chúng (đơn vị bậc bốn) đại diện cho một không gian 3-Sphere, do đó có thể đại diện cho bất kỳ hướng nào, trong khi tôi hiểu các góc Euler mỗi đại diện cho các vòng tròn / turos, do đó không phải là một hình cầu hoàn chỉnh không phải là cách rất chính xác để biểu diễn hướng (3 vòng tròn / hình xuyến thực sự không thể tạo ra mọi hướng có thể trừ khi chúng xoay độc lập, điều này không thể thực hiện được trong trường hợp góc euler), không chắc tôi có giải thích chính xác không :)
concept3d

1

Tích lũy ma trận trong thực tế có thể giải quyết khóa Gimbal. Bằng cách tích lũy các phép quay, bạn đang thêm các khoản tiền, cho phép bất kỳ phép quay tùy ý. Sơ đồ mà ktodisco cung cấp cho thấy một khóa gimbal trong sơ đồ bên trái. Ma trận cho định hướng này có thể được định nghĩa là:

glutil::MatrixStack bookMatrix;
bookMatrix.RotateX(90);
bookMatrix.RotateY(90);
bookMatrix.RotateZ(90);

Do vòng quay y gimbal, các đồng tiền X và Z hiện đã bị khóa, vì vậy chúng tôi đã mất một mức độ chuyển động. Tại thời điểm này, chúng tôi không có ngáp (y địa phương, z toàn cầu) bằng cách sử dụng ba gimbals này. Nhưng bằng cách thêm một gimbal khác, tôi có thể xoay cục bộ xung quanh y:

glutil::MatrixStack bookMatrix;
bookMatrix.RotateX(90);
bookMatrix.RotateY(90);
bookMatrix.RotateZ(90);
bookMatrix.RotateY(90);

Đối với mỗi cuộn, cao độ và ngáp mới, chỉ cần thêm một gimbal khác, TIẾP CẬN chúng vào một ma trận. Vì vậy, mỗi khi cần một vòng quay cục bộ khác, một vòng quay được tạo và nhân với ma trận tích lũy. Như chương đề cập, vẫn còn vấn đề, nhưng khóa gimbal không phải là một trong số đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.