ปัญหาล็อก gimbal ถูกแก้ไขได้อย่างไรโดยใช้การแปลงเมทริกซ์แบบสะสม


12

ฉันกำลังอ่านหนังสือ "การเรียนรู้การเขียนโปรแกรมกราฟิก 3D สมัยใหม่" โดย Jason L. McKesson

ณ ตอนนี้ฉันถึงปัญหาล็อก gimbal และวิธีแก้ปัญหาโดยใช้ quaternions

แต่ที่นี่ที่หน้า Quaternions

ส่วนหนึ่งของปัญหาคือเรากำลังพยายามเก็บการปฐมนิเทศเป็นชุดของการหมุนแกนสะสม 3 ชุด การวางแนวคือการหมุนไม่ใช่การหมุน และทิศทางไม่แน่นอนชุดของการหมุน ดังนั้นเราต้องปฏิบัติต่อการวางแนวของเรือในฐานะการปฐมนิเทศตามปริมาณที่กำหนด

ฉันเดาว่านี่เป็นจุดแรกที่ฉันเริ่มสับสนเพราะฉันไม่เห็นความแตกต่างอย่างมากระหว่างการหมุนและการหมุน ฉันยังไม่เข้าใจว่าทำไมการปฐมนิเทศจึงไม่สามารถแสดงเป็นชุดการหมุนได้ ...

นอกจากนี้:

ความคิดแรกเกี่ยวกับจุดประสงค์นี้คือเพื่อให้การปฐมนิเทศเป็นเมทริกซ์ เมื่อเวลานั้นมาถึงการปรับเปลี่ยนการปฐมนิเทศเราเพียงแค่นำการแปลงไปใช้กับเมทริกซ์นี้โดยจัดเก็บผลลัพธ์เป็นทิศทางปัจจุบันใหม่

ซึ่งหมายความว่าทุก ๆ yaw pitch และ roll ที่ใช้กับการวางแนวปัจจุบันจะสัมพันธ์กับการวางแนวปัจจุบันนั้น ซึ่งเป็นสิ่งที่เราต้องการอย่างแม่นยำ หากผู้ใช้ใช้การหันเหที่เป็นบวกคุณต้องการให้หันเหที่จะหมุนพวกเขาเมื่อเทียบกับที่พวกเขากำลังชี้ปัจจุบันไม่ได้เกี่ยวข้องกับระบบพิกัดคงที่บางส่วน

แนวคิดฉันเข้าใจ แต่ฉันไม่เข้าใจว่าการสะสมการแปลงเมทริกซ์เป็นวิธีแก้ปัญหานี้ได้อย่างไรรหัสที่ให้ในหน้าก่อนหน้านั้นไม่ใช่แค่นั้น

นี่คือรหัส:

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();
}

เพื่อความเข้าใจของฉันไม่ใช่สิ่งที่เขากำลังทำ (แก้ไขเมทริกซ์บนสแต็ก) ซึ่งถือเป็นเมทริกซ์สะสมเนื่องจากผู้เขียนรวมการแปลงการหมุนแต่ละตัวทั้งหมดเป็นเมทริกซ์เดียวซึ่งถูกเก็บไว้ที่ด้านบนสุดของสแต็ก

ความเข้าใจเกี่ยวกับเมทริกซ์ของฉันคือพวกมันคุ้นเคยกับจุดที่สัมพันธ์กับจุดกำเนิด (สมมติว่า ... แบบจำลอง) และทำให้สัมพันธ์กับจุดกำเนิดอื่น (กล้อง) ฉันค่อนข้างมั่นใจว่านี่เป็นคำจำกัดความที่ปลอดภัย แต่ฉันรู้สึกว่ามีบางสิ่งที่ขาดหายไปซึ่งขัดขวางไม่ให้ฉันเข้าใจปัญหาล็อก gimbal นี้

สิ่งหนึ่งที่ไม่สมเหตุสมผลสำหรับฉันคือ: หากเมทริกซ์กำหนดความแตกต่างที่สัมพันธ์กันระหว่าง "ช่องว่าง" สองอันทำไมการหมุนรอบแกน Y สำหรับมาสมมุติว่าม้วนไม่ทำให้ประเด็นอยู่ใน "พื้นที่ม้วน" "ซึ่งสามารถเปลี่ยนได้อีกครั้งในความสัมพันธ์กับม้วนนี้ ... ในคำอื่น ๆ ที่ไม่ควรมีการเปลี่ยนแปลงเพิ่มเติมไปยังจุดนี้จะเกี่ยวข้องกับ" พื้นที่ม้วน "ใหม่นี้และดังนั้นจึงไม่มีการหมุนจะสัมพันธ์กับก่อนหน้านี้" โมเดลพื้นที่ "ซึ่งเป็นสาเหตุของการล็อก gimbal

นั่นเป็นเหตุผลที่ล็อค gimbal เกิดขึ้นใช่มั้ย เป็นเพราะเราหมุนวัตถุรอบแกน X, Y และ Z แทนที่จะหมุนวัตถุรอบ ๆ มันเองแกนสัมพัทธ์ หรือฉันผิด

เนื่องจากรหัสนี้ฉันเชื่อมโยงในไม่ได้เป็นการสะสมของการแปลงเมทริกซ์คุณสามารถโปรดยกตัวอย่างของการแก้ปัญหาโดยใช้วิธีนี้

ดังนั้นโดยสรุป:

  • ความแตกต่างระหว่างการหมุนและการวางแนวคืออะไร?
  • ทำไมรหัสที่ถูกเชื่อมโยงไม่ใช่ตัวอย่างของการสะสมการแปลงเมทริกซ์?
  • อะไรคือจุดประสงค์ที่แท้จริงและเฉพาะเจาะจงของเมทริกซ์ถ้าฉันคิดผิด?
  • วิธีแก้ปัญหาของปัญหาล็อก gimbal สามารถทำได้โดยใช้การสะสมของการแปลงเมทริกซ์?
  • นอกจากนี้ยังเป็นโบนัส: ทำไมการเปลี่ยนแปลงหลังจากการหมุนยังสัมพันธ์กับ "พื้นที่จำลอง"
  • โบนัสอื่น: ฉันผิดในการสันนิษฐานว่าหลังจากการเปลี่ยนแปลงการเปลี่ยนแปลงเพิ่มเติมจะเกิดขึ้นเมื่อเทียบกับปัจจุบัน?

นอกจากนี้หากไม่ได้บอกเป็นนัยฉันกำลังใช้ OpenGL, GLSL, C ++ และ GLM ดังนั้นตัวอย่างและคำอธิบายในแง่ของสิ่งเหล่านี้จะได้รับการชื่นชมอย่างมากหากไม่จำเป็น

ยิ่งรายละเอียดมากเท่าไหร่ก็ยิ่งดีเท่านั้น!

ขอบคุณล่วงหน้า.

คำตอบ:


11

ฉันไม่แน่ใจว่าวิธีที่ดีที่จะนำเสนอสิ่งนี้นอกเหนือจากที่ฉันหวังว่ามันจะเชื่อมโยงเข้าด้วยกันเป็นอย่างดีในตอนท้าย ที่กล่าวว่ามาดำน้ำใน:

การหมุนและการวางแนวจะแตกต่างกันเพราะก่อนหน้านี้อธิบายการเปลี่ยนแปลงและหลังอธิบายถึงสถานะ หมุนเวียนเป็นวิธีการที่วัตถุที่ได้รับในการปฐมนิเทศและการปฐมนิเทศเป็นพื้นที่ที่หมุนท้องถิ่นของวัตถุ สิ่งนี้สามารถเกี่ยวข้องโดยตรงกับวิธีการแสดงทั้งสองทางคณิตศาสตร์: เมทริกซ์จัดเก็บการแปลงจากพื้นที่พิกัดหนึ่งไปยังอีกพื้นที่หนึ่ง (คุณทำถูกต้องแล้ว) และ quaternion อธิบายการวางแนวโดยตรง เมทริกซ์จึงสามารถอธิบายได้ว่าวัตถุเข้าสู่ทิศทางได้อย่างไรผ่านชุดการหมุน อย่างไรก็ตามปัญหาในเรื่องนี้ก็คือ Gimbal Lock

Gimbal lock แสดงให้เห็นถึงความยากลำบากในการทำให้วัตถุเข้าสู่ทิศทางโดยใช้ชุดการหมุน ปัญหาเกิดขึ้นเมื่อแกนหมุนอย่างน้อยสองแกนจัดตำแหน่ง:

รูปภาพเอื้อเฟื้อโดย deepmesh3d.com
ในภาพด้านซ้ายด้านบนแกนสีน้ำเงินและสีส้มหมุนเหมือนกัน! นี่เป็นปัญหาเนื่องจากสิ่งนี้หมายความว่าหนึ่งในสามองศาอิสระหายไปและการหมุนเพิ่มเติมจากจุดนี้อาจให้ผลลัพธ์ที่ไม่คาดคิด การใช้ quaternions แก้ปัญหานี้เพราะใช้ quaternion เพื่อเปลี่ยนการวางแนวของวัตถุโดยตรงจะทำให้วัตถุในการวางแนวใหม่

ตอนนี้ฉันกำลังสงสัยเกี่ยวกับการสะสมเมทริกซ์เป็นวิธีการแก้ปัญหาที่สมบูรณ์เพราะการสะสมเมทริกซ์ วิธีที่เหมาะสมในการจัดการการเปลี่ยนแปลงโดย quaternion คือการดำเนินการคูณ quaternion ในจุด:

pTransformed = q * pAsQuaternion * qConjugate

หรือโดยการแปลงควอเทอร์เนียนเป็นเมทริกซ์และเปลี่ยนจุดโดยใช้เมทริกซ์นั้น

การหมุนเมทริกซ์ธรรมดา (เช่น 45 องศาหันเห) จะถูกกำหนดในพื้นที่ทั่วโลก หากคุณต้องการใช้การแปลงในพื้นที่ท้องถิ่นคุณจะต้องแปลงการแปลงของคุณเป็นวัตถุท้องถิ่นพื้นที่ มันฟังดูแปลกดังนั้นฉันจะทำอย่างละเอียด นี่คือสิ่งที่ความสำคัญของลำดับการหมุนเข้ามาฉันขอแนะนำให้หยิบหนังสือเล่มหนึ่งที่นี่เพื่อให้คุณสามารถติดตามพร้อมกับการเปลี่ยนแปลง

เริ่มต้นด้วยการวางราบหนังสือโดยที่หนังสือจะหันหน้าไปทางเพดานราวกับว่าคุณกำลังจะเปิดหนังสือและเริ่มอ่าน ตอนนี้เอียงหน้าหนังสือขึ้น 45 องศา (ฝาด้านหน้าควรจะหันหน้าเข้าหาคุณ):

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

ทีนี้สมมติว่าคุณต้องการที่จะปรับการหันเหของหนังสือ 45 องศา (ฉันคิดว่าฉันถือว่าระบบพิกัดมือขวาดังนั้นสิ่งนี้จะเปลี่ยนไปทางซ้าย) และคุณต้องการให้มันใช้กับท้องถิ่นของหนังสือ ประสานงานพื้นที่เพื่อที่หน้าปกของหนังสือจะยังคงเผชิญกับคุณ:

bookMatrix.RotateY(45);

ปัญหาคือการหมุนนี้เกิดขึ้นในพื้นที่ประสานงานระดับโลกดังนั้นหน้าปกของหนังสือจะสิ้นสุดที่ไหล่ขวาของคุณ หากต้องการให้การเปลี่ยนแปลงในส่วนหัวนี้เกิดขึ้นในพื้นที่ประสานงานในพื้นที่คุณควรใช้มันก่อน!

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

ลอง! เริ่มหนังสือหันหน้าไปทางเพดานอีกครั้ง เปลี่ยนหันเห 45 องศาแล้วขว้าง 45 องศาตามแกน X ทั่วโลก (วิ่งจากซ้ายไปขวา) นี่คือการวางแนวที่คุณคาดหวังด้วยระดับ 45 และหันเห 45 จากพื้นที่ของหนังสือ

สิ่งนี้หมายความว่า? ทั้งหมดที่จริงลงมาคือลำดับของการปฏิบัติการมีความสำคัญ การแปลงรูปเสร็จแล้วกลายเป็นการแปลงสภาพในบริบทของการเปลี่ยนแปลงที่เกิดขึ้นหลังจากนั้น มันเป็นเรื่องที่ต้องห่อหัวของคุณไปรอบ ๆ และนี่คือวิธีที่ quaternions ช่วยชีวิตได้มาก ข้ามสิ่งที่ขึ้นอยู่กับการสั่งซื้อทั้งหมด

ข้อดีอีกอย่างที่ quaternions จัดเตรียมไว้ให้คือพวกเขายอมให้มีการแก้ไขการวางแนว การพยายามที่จะสอดแทรกระหว่างมุมออยเลอร์แทบเป็นไปไม่ได้เพราะการพึ่งพาคำสั่ง คุณสมบัติทางคณิตศาสตร์ของ quaternion อนุญาตให้มีการแก้ไขเชิงเส้นทรงกลมที่กำหนดไว้อย่างดีระหว่างพวกเขา

ในการสรุปและตอบคำถามเดิมของคุณ: การแปลงเมทริกซ์แบบสะสมจะไม่สามารถแก้ปัญหาการล็อก Gimbal ได้เว้นแต่ว่าจะมีการเลือกการแปลงอย่างระมัดระวังและนำไปใช้อย่างแม่นยำ ดังนั้นให้ใช้ quaternions เสมอและใช้ quaternions กับคะแนนโดยใช้การคูณ quaternion

หวังว่าจะช่วย :)


4
สำหรับบันทึกแล้ว quaternions ยังสามารถแนะนำ gimbal lock ถ้าอธิบายผ่านมุมออยเลอร์; ในขณะที่คุณกำลังทำการคำนวณแบบเดียวกันในวิธีที่แตกต่างกัน (quaternions แทนที่จะเป็นเมทริกซ์)
concept3d

1
@ concept3d - ขอแสดงความยินดีกับการกล่าวถึงเรื่องนี้! สิ่งสำคัญคือต้องเข้าใจสิ่งที่ทำให้กลไก gimbal มีแนวโน้มที่จะสูญเสียระดับความเป็นอิสระ: มันเหมือนหุ่นยนต์ที่มีข้อต่อโดยเนื้อแท้ที่อธิบายถึงระบบสมการ overdetermined หากคุณสร้างกลไกนี้ด้วย quaternions การฝึกอบรมหรือเวทย์มนตร์คุณยังคงมีความคลุมเครือ - มันเข้าใจและไม่ใช้มันในตอนแรกนั่นคือทางออกที่แท้จริง .
Teodron

quaternions ยากที่จะจินตนาการวิธีที่ฉันมักจะคิดเกี่ยวกับมันก็คือพวกเขา (หน่วย quaternions) เป็นตัวแทนของ 3-Sphere พื้นที่ดังนั้นจึงสามารถเป็นตัวแทนของการวางแนวใด ๆ ในขณะที่ฉันเข้าใจมุมออยเลอร์แต่ละวงกลมแทน / turos ไม่ได้เป็นวิธีที่ถูกต้องมากจะเป็นตัวแทนของการปฐมนิเทศ (3 แวดวง / พรูไม่สามารถจริงๆสร้างทุกการวางแนวทางที่เป็นไปได้จนกว่าพวกเขาจะหมุนได้อย่างอิสระซึ่งเป็นไปไม่ได้ในกรณีของมุมออยเลอร์) ไม่แน่ใจว่าถ้าผมอธิบายได้อย่างถูกต้อง :)
concept3d

1

การสะสมเมทริกซ์สามารถแก้ไข Gimbal lock ได้ โดยการสะสมการหมุนคุณกำลังเพิ่ม gimbals อนุญาตการหมุนโดยพลการใด ๆ แผนภาพที่ ktodisco จัดไว้ให้แสดงการล็อก gimbal ในแผนภาพด้านซ้าย เมทริกซ์สำหรับการวางแนวนี้สามารถกำหนดเป็น:

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

เนื่องจากการหมุน y yim, gimbals X และ Z ถูกล็อคดังนั้นเราจึงสูญเสียการเคลื่อนไหวไปหนึ่งระดับ ณ จุดนี้เราไม่มีการหาว (local y, global z) โดยใช้ gimbals ทั้งสามนี้ แต่ด้วยการเพิ่ม gimbal อีกอันฉันสามารถหมุนโลคอลรอบ y ได้:

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

สำหรับม้วนท่ีพิทช์และหันเหใหม่ให้เพิ่ม gimbal อีกอันหนึ่งการสะสมพวกมันเป็นเมทริกซ์เดียว ดังนั้นทุกครั้งที่ต้องการการหมุนในท้องถิ่นอีกครั้งการหมุนจะถูกสร้างและคูณกับเมทริกซ์การสะสม บทที่กล่าวถึงยังคงมีปัญหาอยู่ แต่การล็อกแบบ gimbal ไม่ใช่หนึ่งในนั้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.