الشبكة العربية لمطوري الألعاب

خبير مشرف مؤيد مارديني مشاركة 1

مرحباً
إذا رسمت Curve باستخدام الروتين DrawCurve الموجود في الطبقة System.Drawing.Graphics و أردت أن أرسم نفس الشكل تماماً باستخدام DrawBezier, كيف يمكنني استنتاج نقاط الـ Bézier الأربعة التي تنتج نفس الشكل من نقاط الـ Curve الثلاثة (طبعاً النقطة الأولى و الأخيرة لن تختلف بين الـ Bézier و الـ Curve)
شكراً
Moayad Mardini

Moayad Mardini,
MSDN Forums Moderator

محترف مشرف عبد اللطيف حاجي علي مشاركة 2

يمكننا النظر لهذه المشكلة من زاوية أخرى (أكثر منطقية ربما)، نريد إيجاد الـ Control Points لـ Bezier يمر بنقطة معينة (طبعاً هذا سيخلق مشكلة جديدة، سأشرحها بعد قليل)...
حسناً، لنبدأ من بداية البداية، من طريقة رسم الـ Bezier Curve. لإيجاد النقاط التي تنتمي لـ Bezier معين، نستخدم المعادلة التالية:



حيث P1,P4 هما نقطتا البداية و النهاية للـ Bezier Curve و P2,P3 هما الـ Control Points
طبعاً هذه المعادلة تمّ استخراجها عبر سلسلة من النظريات و البراهين و الاستنتاجات التي لسنا في صددها الآن. ما يهمنا الآن هو أن هذه المعادلة هي في الحقيقة معادلتان:


X = ((-t3+3*t2-3*t+1)*P1.X+(3*t3-6*t2+3*t)*P2.X+(-3*t3+3*t2)*P3.X+t3*P4.X);

Y = ((-t3+3*t2-3*t+1)*P1.Y+(3*t3-6*t2+3*t)*P2.Y+(-3*t3+3*t2)*P3.Y+t3*P4.Y);


لاحظ هنا أن المتغير t هو المتغير المستقل والذي يأخذ قيمه من المجال [1,0] وبالفعل فعندما تكون t=0 تكون النقطة الناتجة هي نقطة البداية P1 و عندما تكون t=1 تكون النقطة الناتجة هي نقطة النهاية P4...
الآن كل ما نحتاجه هو أن نوجد P2 و P3 عندما يعلم لدينا P1 و P4 و نقطتان ناتجتان، هذا سيعطينا 4معادلات و ووجع رأس... في حالتنا الخاصة حيث لدينا نقطة واحدة من الـ Bezier نستطيع أن نعتبر أن P2=P3 وبهذا يصبح لدينا معادلتان بمجهولان:

P2.X = P3.X = - (((-t3+3*t2-3*t+1)*P1.X+t3*P4.X - X )/(-3*t2+3*t));
P2.Y = P3.Y = - (((-t3+3*t2-3*t+1)*P1.Y+t3*P4.Y - Y )/(-3*t2+3*t));


هنا تأتي المشكلة، لاحظ أنه من أجل كل قيمة لـ t سينتج Control Points جديدة و منحني Bezier جديد يمر بالنقطة المعطاة.
الآن لنعد إلى نص المسألة: يجب أن نطابق المنحني الناتج من DrawCurve، ولكن المنحني الناتج من DrawCurve يغير اتجاهه (ينعطف) عند النقط المعطاة, إذاً يجب أن نجد القيمة التي يغير التابع السابق جهته عندها، بطريقة ما: سنجد أنها t=0.5, و بتعويض هذه القيمة نستطيع أن نوجد المطلوب...

كما تلاحظ فإن هذا الحل ليس كاملاً، فمثلاُ أنا افترضت أن الـ Bezier الذي يمر بنقطة وحيدة يمكن تحديده بـ Control Point وحيدة وهذا أمر يحتاج إلى برهان، أيضاً القيمة t=0.5 وجدتها عن طريق التجريب و هي تحتاج إلى برهان أيضاً... و هذا ما أعمل عليه الآن

عبد اللطيف حاجي علي
مبرمج
In|Framez

خبير مدير وسام البهنسي مشاركة 3

أعجبتني فكرة جعل الـ Bezier يمر من نقطتين بدلاً من "التوجه نحوهما" عن طريق جعل هاته النقطتين هما بدايته ونهايته. فكرة لطيفة... إذا انطبقت نقطتي المنتصف لـ Bezier فهذا يعني المزيد من الشد نحوهما (tension)، لا أدري إن كان المنحني الناتج قرب المنتصف سيظهر بشكل قريب من الـ curve المستعمل في DrawCurve، لكنها تجربة تستحق المحاولة... مؤيد؟


MSDN Game Technology Forums Moderator

وسام البهنسي
مبرمج في إنفيديا وإنفريمز

محترف مشرف عبد اللطيف حاجي علي مشاركة 4

التعليق على مشاركة وسام البهنسي في Mar 27, 2006 10:16 :

> أعجبتني فكرة جعل الـ Bezier يمر من نقطتين بدلاً من
> "التوجه نحوهما" عن طريق جعل هاته النقطتين هما بدايته
> ونهايته. فكرة لطيفة... إذا انطبقت نقطتي المنتصف لـ
> Bezier فهذا يعني المزيد من الشد نحوهما (tension)، لا
> أدري إن كان المنحني الناتج قرب المنتصف سيظهر بشكل قريب
> من الـ curve المستعمل في DrawCurve، لكنها تجربة تستحق
> المحاولة... مؤيد؟

أنا نفسي لا أفهمك هنا، أنا لم أقل أن النقطتين هما بداية و نهاية الـ Bezier. ناهيك عن أن فكرتك هذه سوف تزيد المهمة تعقيداً بقسم الـ Bezier إلى اثنين و تطبيق ما تكلمت عنه عليهما.

ولكن فكرتك هذه أوحت لي بتساؤل: هل يمكننا رسم منحني يمر بأكثر من 4 نقاط بالـ Beziers؟ وهل سينطبق المنحني الناتج مع المنحني الناتج من DrawCurve؟ (طبعاً لا نستطيع رياضياً أن نرسم Bezier يم بأكثر من أربع نقاط "ليست على Bezier واحد")
أعتقد أن هذا أمر يستحق التجريب...

عبد اللطيف حاجي علي
مبرمج
In|Framez

خبير مشرف مؤيد مارديني مشاركة 5

التعليق على مشاركة وسام البهنسي في Mar 27, 2006 10:16 :
> أعجبتني فكرة جعل الـ Bezier يمر من نقطتين بدلاً من
> "التوجه نحوهما" عن طريق جعل هاته النقطتين هما بدايته
> ونهايته. فكرة لطيفة... إذا انطبقت نقطتي المنتصف لـ
> Bezier فهذا يعني المزيد من الشد نحوهما (tension)، لا
> أدري إن كان المنحني الناتج قرب المنتصف سيظهر بشكل قريب
> من الـ curve المستعمل في DrawCurve، لكنها تجربة تستحق
> المحاولة... مؤيد؟

كذلك أنا, لم أفهم قصدك تماماً, قد أعيد صياغة السؤال بحيث يصبح "هل يمكنني جعل Bezier يمر من نقطة محددة مع الانطباق مع المنحني الذي يرسمه DrawCurve()"
شكراً لكما لهذه المعلومات سأقوم بدرستها لمحاولة الاستفادة منها...
Moayad Mardini

Moayad Mardini,
MSDN Forums Moderator

خبير مدير وسام البهنسي مشاركة 6

للمرجعية، هذه الصفحة ممتازة كمنطلق لشرح منحنيات بيزييه وشتى العمليات الشائعة التي يمكن أن تتم عليها:
https://pomax.github.io/bezierinfo/

وسام البهنسي
مبرمج في إنفيديا وإنفريمز