كيفية تدوير المصفوفة وتغيير حجمها وترجمتها مرة واحدة في لغة C#؟

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

  •  10-07-2019
  •  | 
  •  

سؤال

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

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

أعتقد أن هذا سيفعل ذلك:

        Point center = new Point( 50, 50 );
        float width = 60;
        float height = 100;
        float angle = 0.5;
        Vector3 axis = new Vector3( center.X, center.Y, 0 );
        axis.Normalize();
        Matrix m = Matrix.Scaling( width, height, 0 ) *
            Matrix.RotationAxis( axis, angle ) *
            Matrix.Translation( center.X, center.Y, 0 );

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

لقد حاولت هذا أيضًا:

  Matrix m = Matrix.Transformation2D( new Vector2( center.X, center.Y ), 0f,
      new Vector2( width, height ), new Vector2( center.X, center.Y ),
      angle, Vector2.Zero );

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

هذا كله في SlimDX.ما الخطأ الذي افعله؟

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

المحلول

لقد مررت للتو بألم تعلم تحويل المصفوفة، ولكن باستخدام XNA.

وجدت هؤلاء مقالات ل يكون جداً مفيدة في فهم ما يحدث.استدعاءات الطريقة متشابهة جدًا في XNA ويجب أن تنطبق عليك النظرية الكامنة وراءها، حتى مع SlimDX.

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

الترتيب الذي سأفعله به هو:

  • ترجم إلى الأصل
  • حجم
  • استدارة
  • ترجم إلى الموقع المطلوب

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

نصائح أخرى

حسنا، هذا وتعمل الآن. وهنا قال لي رمز العمل لهذا، في حالة شخص آخر يحتاج إليه:

    Point sourceLoc = new Point ( 50, 50 );
    float length = 60;
    float thickness = 2;
    float angle = 0.5;
    Matrix m = Matrix.Scaling( length, thickness, 0 ) *
            Matrix.RotationZ( angle ) *
            Matrix.Translation( sourceLoc.X, sourceLoc.Y, 0 );
    sprite.Transform = m;

    sprite.Draw( this.tx, Vector3.Zero, Vector3.Zero, Color.Red );

وهذا سوف رسم خط الزاوية طول اخترتها، مع سمك يساوي سمك اخترتها (بافتراض الملمس الخاص بك هو 1x1 بكسل صورة بيضاء). موقع المصدر حيث الخط سوف تنبعث منها، مع أي زاوية تحددها (بالراديان). حتى إذا كنت تبدأ من الصفر والزيادة من شيء من هذا القبيل 0.1 حتى تصل 2PI، ومن ثم إعادة تعيين إلى 0، سيكون لديك خط التي تدور حول مركز مثل يد على مدار الساعة أو الاجتياح الرادار. هذا هو ما كنت أبحث عنه! - الشكر لجميع من ساهم

هل تدور حول محور الصحيح؟ أنا مبتدئ في الاشياء مصفوفة، ولكن يبدو لي أنه منذ العفريت موجود في س، ص الفضاء، محور دوران يجب أن يكون Z-المحور - أي (0،0،1).

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

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

بالنسبة لمشكلتك المحددة، قد تكون المشكلة تتعلق بالتناوب.بعد أن قمت بتحجيم الخط وتدويره، أصبح الخط الآن خارج المركز مما يسبب لك مشاكل أثناء الترجمة.

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

الرد على التعليقات

إذا كانت الترجمة مشكلة وكنت تقوم بتحويل نظام الإحداثيات، فسوف تحتاج إلى كتابة دالة تحويل للتحويل بين النظام القديم والجديد.

على سبيل المثال، إذا كنت تدور 45 درجة.قبل التدوير، كان بإمكانك الترجمة بمقدار 0,1 للتحرك لأعلى بمقدار 1 بوصة.بعد التدوير، سيتعين عليك الترجمة تقريبًا بمقدار -.70707، .070707 للتحرك لأعلى بمقدار بوصة واحدة مقارنة بنظام الإحداثيات الأصلي.

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