أفضل طريقة لترجمة حركة سحب الماوس إلى دوران ثلاثي الأبعاد لكائن ما

StackOverflow https://stackoverflow.com/questions/107413

  •  01-07-2019
  •  | 
  •  

سؤال

لدي كائن ثلاثي الأبعاد وأتمنى أن أتمكن من تدويره بشكل ثلاثي الأبعاد.أسهل طريقة هي ترجمة حركة الماوس X وY مباشرة إلى دوران حول المحورين Y وX، ولكن إذا كان هناك بعض التدوير على طول كلا المحورين، فإن الطريقة التي يدور بها النموذج تصبح غير بديهية إلى حد كبير (على سبيل المثال.إذا قمت بقلب الجسم 180 درجة حول أحد المحاور، فإن حركتك على طول المحور الآخر تنعكس).

يمكنني ببساطة تنفيذ الطريقة المذكورة أعلاه، ولكن بدلاً من تخزين مقدار التدوير حول المحورين، يمكنني تخزين مصفوفة التدوير الكاملة وتدويرها على طول نفس المحاور لكل عملية سحب بالماوس، لكنني أشعر بالقلق من أن ذلك قد يؤدي إلى بسرعة مشاكل الدقة.

هل كانت مفيدة؟

المحلول

قم بإنشاء مصفوفة تراكمية وقم بتهيئتها بالهوية.

في كل إطار، قم بتطبيق ذلك على عرض النموذج/حالة مصفوفة العالم قبل رسم الكائن.

عند حركة الماوس، قم بإنشاء مصفوفة دوران حول المحور X مع بعض حساسية_ثابتة * delta_x.أنشئ مصفوفة دوران أخرى حول المحور Y للمكون الآخر.اضرب واحدًا ثم الآخر في المجمع.

سوف يتغير المجمع أثناء تحريك الماوس.عند الرسم، سيتم توجيه الكائن كما تتوقع.

كما أن من يتحدث عن الكواترنيونات على حق؛سيبدو هذا جيدًا فقط للتغييرات الإضافية الصغيرة.إذا قمت بسحبه بسرعة بشكل قطري، فلن يدور تمامًا بالطريقة التي تتوقعها.

نصائح أخرى

ربما يكون من الأكثر بديهية تدوير الكائن حول المحور المتعامد مع اتجاه السحب الحالي، إما بشكل متزايد مع كل حركة ماوس، أو نسبة إلى موضع بدء السحب.يوفر الخياران تفاعلات مختلفة قليلاً للمستخدم، ولكل منها إيجابياته وسلبياته.

هناك واضحة نسبيا طريقة لتحويل زاوية ومتجه ثلاثي الأبعاد يمثل المحور الذي يتم تدويره إلى مصفوفة دوران.

أنت على حق في أن تحديث مصفوفة التدوير الأولية من خلال عمليات التدوير المتزايدة سيؤدي إلى أن المصفوفة لم تعد مصفوفة دوران خالصة.وذلك لأن مصفوفة التدوير 3x3 تحتوي على ثلاثة أضعاف البيانات المطلوبة لتمثيل التدوير.

هناك طريقة أكثر إحكاما لتمثيل التدويرات وهي باستخدام زوايا أويلر, ، مع وجود متجه بقيمة 3 كحد أدنى.يمكنك اعتبار الدوران الحالي كمتجه زاوية أويلر، وتحويله إلى مصفوفة، وتطبيق التدوير (تزايدي أو غير ذلك)، وتحويل المصفوفة مرة أخرى إلى متجه زاوية أويلر.من الطبيعي أن تؤدي هذه الخطوة الأخيرة إلى إزالة أي مكون غير دوّار في المصفوفة، بحيث ينتهي بك الأمر مرة أخرى بمصفوفة دوّارة خالصة للحالة التالية.

زوايا أويلر جميلة من الناحية النظرية، إلا أن إجراء التحويلات ذهابًا وإيابًا يتطلب الكثير من العمل.

الخيار الأكثر عملية هو الرباعيات (أيضًا)، وهي ناقلات العناصر الأربعة.تحدد العناصر الأربعة الدوران والمقياس الموحد، ويحدث أنه إذا دخلت وقمت بتطبيع المتجه إلى طول الوحدة، فستحصل على عامل مقياس قدره 1.0.لقد اتضح أنه يمكن أيضًا تحويل قيمة محور الزاوية إلى قيمة كواترنيون بسهولة شديدة

q.x = sin(0.5*angle) * axis.x;
q.y = sin(0.5*angle) * axis.y;
q.z = sin(0.5*angle) * axis.z;
q.w = cos(0.5*angle);

يمكنك بعد ذلك أخذ منتج الرباعي (الذي يستخدم فقط الضرب والجمع البسيط) لرباعي الدوران الحالي ورباعي الدوران المتزايد للحصول على كواترنيون جديد يمثل إجراء كلا الدورتين.عند هذه النقطة، يمكنك تطبيع الطول لضمان التدوير النقي، لكن خلافًا لذلك، يمكنك الاستمرار في الجمع بين التدويرات بشكل متكرر.

يعد تحويل الكواترنيون إلى مصفوفة التدوير أمرًا بسيطًا للغاية (يستخدم الضرب والإضافة فقط) عندما تريد عرض النموذج في حالته الدائرية باستخدام واجهات برمجة تطبيقات الرسومات التقليدية.

في دورة رسومات الكمبيوتر الخاصة بي، تم إعطاؤنا الكود التالي الذي سمح لنا بعدم إعادة اختراع العجلة.

كرة التتبع. h

كرة التتبع.c

يمكنك التعامل مع فقدان الدقة عن طريق إعادة ضبط مصفوفة التدوير الخاصة بك بحيث يكون كل صف من الصفوف الثلاثة متعامدًا مرة أخرى.أو يمكنك إعادة إنشاء مصفوفة التدوير التي أنت على وشك تعديلها بناءً على المعلومات الموجودة حول الكائن، وهذا يلغي الحاجة إلى إعادة التسوية.

بدلا من ذلك يمكنك استخدام كواترنيونز, ، وهو بديل لزوايا أويلر للتعامل مع الدورات.

لقد تعلمت الكثير من هذا في أيامي الأولى هذه الأسئلة الشائعة, ، الذي يتعامل مع هذه المشكلة (على الرغم من تطبيق آخر) في أويلر شريرة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top