ฉันจะหมุนรอบจุดโดยพลการในแบบ 3 มิติ (แทนที่จะเป็นจุดกำเนิด) ได้อย่างไร


15

ฉันมีบางรุ่นที่ฉันต้องการหมุนโดยใช้ quaternions ในลักษณะปกติยกเว้นการหมุนเกี่ยวกับจุดกำเนิดฉันต้องการให้ออฟเซ็ตเล็กน้อย ฉันรู้ว่าคุณไม่ได้พูดว่าในพื้นที่ 3 มิติที่คุณหมุนรอบจุด; คุณบอกว่าคุณหมุนรอบแกน ดังนั้นฉันจึงจินตนาการว่ามันหมุนไปรอบ ๆ เวกเตอร์ซึ่งหางอยู่ในตำแหน่งที่ไม่ได้มาจากแหล่งกำเนิด

การแปลงเลียนแบบทั้งหมดในเครื่องมือเรนเดอร์ / ฟิสิกส์ของฉันถูกเก็บไว้โดยใช้ SQT (สเกล, quaternion, การแปลความคิดที่ยืมมาจากหนังสือGame Engine Architecture ) ดังนั้นฉันจึงสร้างเมทริกซ์แต่ละเฟรมจากส่วนประกอบเหล่านี้ ในระบบนี้การแปลจะถูกนำไปใช้จากนั้นปรับขนาดแล้วหมุน

ในกรณีเฉพาะฉันต้องแปลวัตถุในอวกาศโลกหมุนและหมุนรอบจุดยอดที่ไม่ได้อยู่กึ่งกลางที่จุดกำเนิดของวัตถุ

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


ควอเทอเรียนส์อธิบายการหมุนรอบแกนโดยพลการแล้ว คุณมีปัญหาในการสร้าง quaternion จากข้อมูลที่คุณมีหรือไม่?
Martin Sojka

3
อย่างจริงจังคนที่ยกระดับคำตอบที่อ่านได้จริงหรือไม่? ฉันให้วิธีการสูตรที่มีประสิทธิภาพและแม้แต่การสาธิต ยังมีคำตอบ upvoted เพียงข้อเดียวในขณะที่ให้ข้อมูลที่มีค่าบางอย่าง (และบางข้อมูลที่ผิดอย่างชัดเจน) ไม่มีสิ่งเหล่านี้และไม่ตอบคำถาม!
sam hocevar

@MartinSojka นี่เป็นเรื่องเกี่ยวกับและจุดโดยพลการไม่ใช่แกนใด ๆ
notlesh

@ SamHocevar คำตอบของคุณทั้งสองมีประโยชน์ ฉันเลือกของคุณเพราะมันละเอียดและช่วยฉันแก้ปัญหา ขอบคุณทั้งคู่
notlesh

อ่าขอโทษด้วย - ฉันสับสนกับ Dual Quaternions (ที่ทำให้คุณได้คำแปล "ฟรี" เช่นกัน) ฉันจะเขียนสิ่งที่ฉันต้องการในคำตอบในภายหลัง บางทีคนอื่นอาจเห็นว่ามันมีประโยชน์โดยเฉพาะอย่างยิ่งเนื่องจากคุณสามารถลดองค์ประกอบสามรายการของคุณให้เหลือเพียงองค์ประกอบเดียว - แม้ว่าจะซับซ้อนกว่าเล็กน้อย
Martin Sojka

คำตอบ:


17

ในระยะสั้น

คุณจะต้องเปลี่ยน T ในแบบฟอร์ม SQT ของคุณ

แทนที่เวกเตอร์การแปลvด้วยv' = v-invscale(p-invrotate(p))ซึ่งvเป็นเวกเตอร์การแปลเริ่มต้นpคือจุดที่คุณต้องการให้การหมุนเกิดขึ้นinvrotateและinvscaleเป็นผู้รุกรานการหมุนและสเกลของคุณ

สาธิตด่วน

อนุญาตpเป็นรอบ ๆ rจุดที่คุณใช้การหมุน ให้sเป็นพารามิเตอร์การปรับขนาดvของคุณและเวกเตอร์การแปลของคุณ การเปลี่ยนแปลงเมทริกซ์สุดท้ายคือแทนT(p)R(r)T(-p)S(s)T(v)R(r)S(s)T(v)

สิ่งที่คุณต้องการคือพารามิเตอร์การเปลี่ยนแปลงใหม่v', r'และs'ดังกล่าวว่าการเปลี่ยนแปลงเมทริกซ์สุดท้ายR(r')S(s')T(v')และเรามี:

T(p)R(r)T(-p)S(s)T(v) = R(r')S(s')T(v')

พฤติกรรมที่ไม่มีที่สิ้นสุดบ่งชี้ว่าพารามิเตอร์การหมุนและพารามิเตอร์การสเกลไม่สามารถเปลี่ยนแปลงได้ (ซึ่งสามารถแสดงให้เห็นได้) เราจึงมีและr = r' s = s'พารามิเตอร์ที่ขาดหายไปเพียงอย่างเดียวคือv'เวกเตอร์การแปลใหม่ของคุณ:

T(p)R(r)T(-p)S(s)T(v) = R(r)S(s)T(v')

หากเมทริกซ์เหล่านี้เท่ากันค่าผกผันของพวกมันจะเท่ากัน:

T(-v)S(-s)T(p)R(-r)T(-p) = T(-v')S(-s)R(-r)

โดยเฉพาะอย่างยิ่งนี้ถือเป็นจริงสำหรับแหล่งกำเนิดO:

T(-v)S(-s)T(p)R(-r)T(-p)O = T(-v')S(-s)R(-r)O

การปรับขนาดและการหมุนต้นกำเนิดให้กำเนิดต้นกำเนิดซึ่งจะได้รับ:

T(-v)S(-s)T(p)R(-r)(-p) = -v'

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


ขอบคุณสำหรับคำอธิบาย BTW คุณรู้จักแหล่งข้อมูลที่ฉันสามารถอ่านเพิ่มเติมเกี่ยวกับเทคนิคการเป็นตัวแทน SQT ได้หรือไม่
pachanga

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

15

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

พิจารณาเคส 2 มิติก่อนเพราะมันง่ายกว่าและเทคนิคจะปรับขนาด หากคุณมีก้อนของความกว้าง 2 มีศูนย์กลางอยู่ที่จุดเริ่มต้นและคุณอยากจะหมุน 45 องศาเกี่ยวกับศูนย์ว่าจะเป็นโปรแกรมที่น่ารำคาญของเมทริกซ์หมุน 2D

แต่ถ้าคุณต้องการหมุนรอบ ๆ มันเป็นมุมขวาบน (อยู่ที่1,1) ก่อนอื่นคุณต้องแปลมันก่อน -1,-1นี้สามารถทำได้กับการแปลของ จากนั้นคุณสามารถหมุนวัตถุได้เหมือนก่อน แต่คุณต้องติดตามสิ่งนี้ด้วยการแปลกลับ (โดย1,1) ดังนั้นโดยทั่วไปการบรรลุเมทริกซ์การหมุนRสำหรับการหมุนrประมาณจุดที่Pคุณทำ:

R = translate(-P) * rotate(r) * translate(P)

โดยที่translateและrotateเป็นเมทริกซ์การแปล / การหมุนซึ่งเป็นที่ยอมรับตามลำดับ เมื่อมันเกิดขึ้นเครื่องชั่งนี้จะเป็น 3 มิติซึ่งยกเว้นว่าจะต้องส่งแกนให้กับการหมุนเช่นกัน - คุณสามารถเลือกเมทริกซ์การหมุนแกน X, Y หรือ Z ได้ แต่ก็น่าเบื่อ คุณจะต้องการใช้โดยพลการแกนหมุนมุมเมทริกซ์ ขั้นตอนสุดท้ายของคุณRใน 3D คือ:

R = translate(-P) * rotate(a,r) * translate(P)

โดยที่aเวกเตอร์หน่วยแสดงถึงแกนของการหมุนและPตอนนี้เป็นจุด 3 มิติในพื้นที่จำลองที่เป็นตัวแทนของจุดหมุน

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

นอกจากนี้:

ดังนั้นฉันจึงจินตนาการว่ามันหมุนไปรอบ ๆ เวกเตอร์ซึ่งหางอยู่ในตำแหน่งที่ไม่ได้มาจากแหล่งกำเนิด

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


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

มันลงตัวอย่างสมบูรณ์ภายในข้อ จำกัด ของคุณ เมทริกซ์ R (ผลิตเป็นการแปล - หมุน - แปล - ย้อนกลับ) เป็นเมทริกซ์การหมุนของคุณ แทนที่ Q ด้วย R ในระบบ "SQT" ของคุณเพื่อให้คุณมีกระบวนทัศน์การหมุน - แปล - ทั่วไปที่มากขึ้นและเสร็จสิ้นแล้ว การแปลครั้งสุดท้ายนั้นไม่ขึ้นอยู่กับการแปลระดับกลางสองแบบที่ทำขึ้นเพื่อสร้างการหมุนที่ต้องการ

คุณกำลังเสนอให้ฉันแทนที่ quaternion ด้วยเมทริกซ์หรือไม่? นั่นคือ 12 ไบต์ต่อวัตถุ (8 ถ้าฉันเก็บมันเป็นเมทริกซ์ 4x3)! ฉันจะเงียบคนมองโลกในแง่ดีให้ฉันและให้สิ่งนี้เป็นวน (อันที่จริงอาจจะไม่เพิ่มจำนวนรอยเท้าเพิ่มขึ้น 2kb ... ) ขอบคุณสำหรับคำตอบของคุณ
notlesh

คุณสามารถ - คุณสามารถแปลงระหว่างพวกเขาสร้าง quaternion การหมุนด้วยวิธีนั้นและเสียบกลับเข้าไปในระบบที่มีอยู่ของคุณ

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