الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

[شبه مكتمل] : المرحلة الأولى: تطوير وحدة Core

رائج
بدأه فريق الأندلس في 27 سبتمبر 2009 · 177 رد · 11,907 مشاهدة · في قسم برمجة الألعاب و الرسوميات العام
مشاركة: واتساب X فيسبوك تيليجرام
#76

أليس للمتجه زاوية لتحديد إتجاهه؟

أود ان اشترك في فريق تطوير الجافا

الايميل غير صحيح

يرجى تصحيح الايميل برسالة لأحد مدراء المنتدى

#77

السلام عليكم ....

ماشاء الله يا شباب عمل جدي جداً و منظم :)

لي ملاحظة بسيطة فقط.....

اقتباس
- سنستخدم الاستثناءات في الجافا و لغات الدوت نت .

الاستثناءات في Java و NET. أبطأ بكثير من الموجودة في ++C. أنتم قمتم بالتغاضي عنها من أجل الكفاءة, و قبلتم العمل بها رغم أنها أبطأ في Java و Net.

أرى أن لا تسيروا عكس التيار. لسببين, الأول, أنه سيصبح هناك نسختان من المحرك, واحدة بالاستثناءات و الأخرى بدون, و هذا يعني تصميمين مختلفين. من الصعب جداً أن يكون هناك استثناءات, و أخطاء C-Style في نفس الوقت.

السبب الثاني, هو أنكم تسيرون عكس اللغة نفسها. المكان الوحيد الذي لا يحبذ فيه استخدام الاستثناءات في ++C هو الـ Hard Real Time Systems! و لا أعتقد أن المحرك يمكن أن يكون كذلك, عموماً انظر إلى EASTL, مكتبة لصناعة Data Structure معدلة من STL خاصة بـ EA.

هل تريد القول بأن المحرك الذي تستخدمونه يتطلب أكثر مما تتطلبه هذه المكتبة؟

هناك أسباب أخرى بالطبع. لا تستخدموا أبداً المؤشرات في واجهة محرككم على الإطلاق. بالطبع أنت حر باستخدامها في الـ Implementation. و إن كان هناك حاجة فعليكم بـ shared_ptr, الذي سيصبح فعلياً في Cpp0x.

واجهة المحرك لا يجب أن تعتمد على الـ raw pointers, لأن ذلك سيصعب استخدام المحرك, و سيجعل أخطاء كثيرة تظهر دون اكتشافها, فمثلاً ماهو الخطأ الشنيع في هذا الكود:

void SomeFunctionInYourEngine(...)
{
	// some magic...

	//...
	throw SomeException();
	//...
}

void someOtherFunction()
{
	int* someArray = new int[...];

	SomeFunctionInYourEngine(someArray);

	delete[] someArray;
}

الدالة الأولى مثلاً أحد دوال واجهة المحرك, و الثانية قام المستخدم بكتابتها. هل تستطيع اكتشاف الخطأ؟ بالطبع لاداعي لاستخدام المؤشرات في واجهة المحرك لتفادي هذا الأمر.

الأمر الآخر, لماذا تقوم بتكرار دوال موجودة أصلاً في جميع اللغات التي سيبنى فيها المحرك؟ كدوال الرياضيات, أرى أنها ناقصة و اللغات المقترحة تحتوي بالفعل على مجموعة أكبر من الدوال.

أرى أن تقوموا بكتابة الناقص فقط مما يحتاجه المحرك.

لا أريد الإكثار, و لكن لأني رأيت أن الأخوة ماشاء الله يعملون بطريقة منظمة أحببت المشاركة بما لدي. و عذراً إن كان الاقتراح حول شيء تم تقريره بالفعل :)

تحياتي....

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 30 سبتمبر 2009 في 21:43

#78
class Vector2
{
public:
	float x, y;

لماذا إستخدمت ال generics مع ال Point2D ولم تستخدمها هنا ؟؟

تم تعديل هذه المشاركة بواسطة *خلدون خالد* في 30 سبتمبر 2009 في 21:54

#79

@ بالنسبة لمسألة الاستثناءات في لغة السي بلس، للامور التي ذكرها الاخوة وخصوصا الاخ خالد ، ما رأيكم أن نؤجل العمل بها حتى الاصدار 0.2 .

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

@ الاستثناءات في الجافا والدوت نت :

اقتباس
الاستثناءات في Java و NET. أبطأ بكثير من الموجودة في ++C. أنتم قمتم بالتغاضي عنها من أجل الكفاءة, و قبلتم العمل بها رغم أنها أبطأ في Java و Net.

لكن أخي خالد هي مستخدمة في كل أجزاء اللغة وصارت تقريبا عرفاً للمبرمجين بتلك اللغات ( مثلا في I/O .. لا نستخدم الا الاستثناءات في اقتناص الاخطاء ) ، لا أعرف ان كانت بطيئة أم لا ، أنت أعرف مني بهذا ;) ، ولكن بما انها أصحبت عادة عند أولئك المبرمجين فلنستخدمها .

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

@ المؤشرات الذكية وادارة الذاكرة في السي بلس :

سنستخدم مؤشرات عادية في قلب المحرك ، وفي واجهة المحرك هناك بعض الكائنات سيديرها المحرك ، وهناك كائنات أخرى تقع على عاتق المستخدم . لأن هذا الموضوع كبير نوعا ما .. هناك أمور مثل Resource Management حسب ما قرأت تحل بعض المشاكل ، لكن من الأفضل أن نناقشها في المرحلة الثانية من المحرك 0.2 .. بما في ذلك استخدام خدمات boost كاملة .

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

@ الدوال الرياضية :

اقتباس
الأمر الآخر, لماذا تقوم بتكرار دوال موجودة أصلاً في جميع اللغات التي سيبنى فيها المحرك؟ كدوال الرياضيات, أرى أنها ناقصة و اللغات المقترحة تحتوي بالفعل على مجموعة أكبر من الدوال.

أظن أننا يمكننا العمل على المحرك باستخدام جزء من هذه الدوال ، وكما هي العادة ، في 0.2 ستتغير الامور :D ، تغليفنا لهذه الدوال هو فقط لتسهيل وتوحيد العمل ، ويمكننا في وقت لاحق اعادة كتابة الدوال مثل sqrt بطريقة أسرع .

اقتباس
أود ان اشترك في فريق تطوير الجافا

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

اقتباس
حيث ان المواصفات مكتوبه على هيئة pseudo code فلا داعى لوضعها على svn يمكن وضعها هنا كمرفقات و يقوم كل فريق بوضعها داخل الـ svn الخاصه بنسخة المشروع التى يعمل عليها كنسخه حقيقة جاهزه للتضمين.

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

نأتي للمهم :

كلاس vector : أرى أن اقتراح الاخ خلدون جيد ، نضعه generic أفضل ، ثم نضع نسخة خاصة float الا ان كان لك هدف من جعله float فقط ؟

بالنسبة للـ method ، أرى أنها كافية باستثناء جزء من اضافات طرحها الاخ "مقاوم" .. في مشاركة سابقة

@Purpose : get the dot product of v1 and v2

public static int dotProduct(Vector2D v1, Vector2D v2);

حيث أن هذ الاسم سيستخدم في الجافا .. أما السي بلس فيمكن استخدامه بالاضافة للمعامل ( * ) .. أو يمكن الاكتفاء بالمعامل *

لدي سؤال عن اخر دالتين :

operator float*(); // get start point as array of floats

	Vector2 rotate(float t); // rotate vector

الاولى ، هل يمكن كتابته كاسم للدالة واستخدام [ ] للدالة على المصفوفة ، ويمكنك بعد ذلك في السي بلس استخدام هذا operator .

أعتقد أنه يمكن كتابتها كذا ( أظن أنك تقصد أنه يعيد vector على شكل مصفوفة مكونة من عنصرين .. صحيح ؟؟ ) :

// return vector as array of two elements x and y .
float  [ ] asArray();

أما الدالة rotate ، هل تقصد عمل دوران للمتجه أو النقطة .. لا أعرف أيهما أصح تسمية :) ،أعتقد هذه من مهام matrix حيث ستحوي على شيء كهذا .

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#80
اقتباس
أما الدالة rotate ، هل تقصد عمل دوران للمتجه أو النقطة .. لا أعرف أيهما أصح تسمية ،أعتقد هذه من مهام matrix حيث ستحوي على شيء كهذا .

بالمناسبة لماذا لا نضع دوال ال Transformation داخل كلاس ال Vector أو إختصار لها على الأقل (لا أدري إذا كان يوجد شيئ إسمه إختصار :)) أعلم أن هذه الدوال موقعها الصحيح هو في داخل الفئه matrix ولكن مجرد إقتراح للنقاش ...

#81
اقتباس
@ بالنسبة لمسألة الاستثناءات في لغة السي بلس، للامور التي ذكرها الاخوة وخصوصا الاخ خالد ، ما رأيكم أن نؤجل العمل بها حتى الاصدار 0.2 .

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

كما تريد، و لكن يبدو انه يوجد الكثير لنتحدث عنه داخل الإصدار 0.2 و اخشى ان يتم تأجيله للإصدار 0.3 :wink:

اقتباس
الاستثناءات في Java و NET. أبطأ بكثير من الموجودة في ++C. أنتم قمتم بالتغاضي عنها من أجل الكفاءة, و قبلتم العمل بها رغم أنها أبطأ في Java و Net.

كما ذكرنا الإستثناءات تبطئ من عمل البرامج الـ Native فما بالك بالبرامج المبنيه على VM.

اقتباس
هناك أسباب أخرى بالطبع. لا تستخدموا أبداً المؤشرات في واجهة محرككم على الإطلاق. بالطبع أنت حر باستخدامها في الـ Implementation

لابد من جعل واجهة المحرك بسيطه و يسهل التعامل معها و لنترك التعقيدات داخل الـ Implementation حيث ان المحرك ماهو إلا واجهه التى يتم إستخدامها فإذا اصبحت غير امنه (بوجود المؤشرات) فما الهدف منه ؟؟

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

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

اقتباس
الأمر الآخر, لماذا تقوم بتكرار دوال موجودة أصلاً في جميع اللغات التي سيبنى فيها المحرك؟ كدوال الرياضيات, أرى أنها ناقصة و اللغات المقترحة تحتوي بالفعل على مجموعة أكبر من الدوال.

هذا من ضمن الأسئله التى وردت بذهنى، فهل سنقوم بإعادة برمجة تلك الدوال ام كيف سنقوم بإستخدامها ؟ (لقد قمت ببرمجتهم فى موضوع سابق)

اقتباس
لدي سؤال عن اخر دالتين :

operator float*(); // get start point as array of floats
	Vector2 rotate(float t); // rotate vector

بالنسبه للداله الأولى فأنا اقصد فعلا كتابتها بالشكل التالى حيث انها ستعود بمصفوفه من عنصرين هما x و y و شكل الكود الخاص بها كالتالى

 

Vector2[color= #000000;]::[color= #808000;]operator [color= #0000ff;]float[color= #000000;]*[color= #000000;]([color= #000000;])

[color= #000000;]{ [color= #0000ff;]return [color= #000000;]&x; [color= #000000;]}

بما ان المتغيرين x و y تم التصريح عنهما بشكل متتالى فسيتم حجز مساحتهم بالذاكره بشكل متتالى لذلك عندما اعود بموقع العنصر الأول يمكن الدخول للعنصر الثانى بسهوله حيث انه يليه.

بالنسبه للداله الثانيه، فهى غير منطقيه حيث ان الدوران متاح فقط للمتجهات ثلاثية الأبعاد.

و الله ولى التوفيق

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 1 أكتوبر 2009 في 00:41

مدونتي: C++ Tips and Tricks

#82
اقتباس
بالمناسبة لماذا لا نضع دوال ال Transformation داخل كلاس ال Vector أو إختصار لها على الأقل (لا أدري إذا كان يوجد شيئ إسمه إختصار ) أعلم أن هذه الدوال موقعها الصحيح هو في داخل الفئه matrix ولكن مجرد إقتراح للنقاش ...

أرى أن المكان الانسب هو Matrix .. صوت بصوت وننتظر بقية الاصوات ;) .

اقتباس
كما تريد، و لكن يبدو انه يوجد الكثير لنتحدث عنه داخل الإصدار 0.2 و اخشى ان يتم تأجيله للإصدار 0.3

:D ..

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

نعم .. كلامك صحيح .. دعني أوضح هذه النقطة .

الاصدارة 0.2 : ستحوي اضافات للمحرك ( حوالي 70% اضافات للمحرك - 20% تعديلات في implementation - و 10% تعديل في واجهة المحرك النهائية )

فمثلا : سيتم الحديث عن Resource Management وهو أحد الأسس في محركات الألعاب ( يمكن البحث عنه لمعلومات أكثر ) ، وتعتمد على بعض المبادئ مثل reference counter حسب ما أعرف ، وهي اضافة مستقلة عن قلب المحرك .

أما boost يمكن استخدامها في السي بلس في أمور اضافية وليس لتعديل الوضح الحالي للمحرك ، يمكن استخدامها لاضافة Class لتحويل الأعداد الى نصوص والعكس أو لتحويل العدد العشري الى صحيح والعكس .

يمكن استخدام shared_ptr في Resource Management ان امكن .. وفي مواقع أخرى ( لن نستخدمها الا عندما نحتاجها ) .

يمكن استخدام boost في الكلاس Random .

يمكن استخدام boost في serialization أو في threads .

يمكن استخدام boost لو أحببنا دعم ملفات xml مثلا .

لذلك كل الاستخدامات ستكون عبارة عن اضافات .. غير موجودة في الاصدار 0.1 ، لذلك لاخوف من تغير تصميم المحرك ( ستكون التعديلات طفيفة جدا في واجهة المحرك ان شاء الله ) .

ما رأيكم أن نبدأ في matrix :D .. أظن أن الوقت ليس في صالحنا .. بالنسبة للـ Vector رح نعتمد النسخة التي طرحها الاخ محمد مع بعض التعديلات وأي اضافة مهمة يتم طرحها في هذا الموضوع .

Matrix :

أول سؤال : ماهو نظام matrix الذي سنعتمده ؟

هناك نظامين :

column-major order : وهو يقوم على ترتيب عناصر المصفوفة بشكل عمودي - هكذا :

[	a0	a3	a6	]
[	a1	a4	a7	]
[	a2	a5	a8	]

وبالتالي تختلف مصفوفة الازاحة مثلا حسب النظام المستخدم .. وعملية الضرب تجري من اليمين لليسار ( أي أننا سنضرب مصفوفة التحجيم scale بالمتجه ثم الناتج وهو متجه عمودي ان صح التعبير نضربه في مصفوفة الازاحة ) .

[	1	0	xT	]	 [   xS   0	0   ]   [xPoint]
[	0	1	yT	]	 [	0   yS   0   ]   [yPoint]
[	0	0	1	 ]	 [	0   0	1   ]   [1]

الطريقة السابقة متبعة في OpenGL و Ogre وكثير من الكتب المتخصصة في برمجة الرسوميات . كما أن كثيراً من الجامعات تعتمد على هذا الأسلوب في تدريس المادة .

row-major order : يرتب عناصر المصفوفة بشكل أفقي هكذا :

[	a0	a1	a2	]
[	a3	a4	a5	]
[	a6	a7	a8	]

و عملية الضرب تتم من اليسار الى اليمين هكذا :

[xPoint yPoint	   1   ] *		[	a0	a1	a2	]
										 [	a3	a4	a5	]
										 [	a3	a4	a5	]

الطريقة السابقة مستخدمة في Direct3D .. و irrlicht وبعض المكتبات الاخرى .

يمكن استخدام أحد الطرق والانتقال الى الاخر عن طريق منقول المصفوفة transpose . لكن نريد رأيكم في هذا الموضوع .

بالاضافة إلى أهم الدوال Methods في هذا الكلاس .

( عمليات Transformation ستكون في داخل Matrix ) .

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#83
اقتباس
بالمناسبة لماذا لا نضع دوال ال Transformation داخل كلاس ال Vector أو إختصار لها على الأقل (لا أدري إذا كان يوجد شيئ إسمه إختصار ) أعلم أن هذه الدوال موقعها الصحيح هو في داخل الفئه matrix ولكن مجرد إقتراح للنقاش ...

كل فى مكانه بمعنى دوال التحويل الخاصه بالمصفوفات يتم وضعها داخل النوع Matrix كذلك دوال التحويلات الخاصه بالمتجهات يتم وضعها داخل النوع Vector.

اقتباس
أول سؤال : ماهو نظام matrix الذي سنعتمده ؟

row-major order لإنه هو الإفتراضى فى التعامل مع المصفوفات بشكل عام فى الرياضيات

معذره لم ارى هذا السؤال

اقتباس
الكلاس vector : أرى أن اقتراح الاخ خلدون جيد ، نضعه generic أفضل ، ثم نضع نسخة خاصة float الا ان كان لك هدف من جعله float فقط ؟

لا احبذ موضوع ان كل الأنواع الرياضيه ان تكون generic و السبب فى ذلك عندما نبدأ فى التكلم عن محرك الفيزياء و خصوصا الفئه الخاصه بالـ collision detection سنحتاج للتعامل مع المتجهات و هذا سيؤدى بنا لجعل اغلب الدوال generic و بهذا يصبح المحرك بأكمله داخل ملفات header.

جارى عمل بعض التعديلات على نسخة الـ Matrix لوضعها لكم.

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#84

عفوا لم أنتبه لسؤالك أخ محمد ..

اقتباس
هذا من ضمن الأسئله التى وردت بذهنى، فهل سنقوم بإعادة برمجة تلك الدوال ام كيف سنقوم بإستخدامها ؟ (لقد قمت ببرمجتهم فى موضوع سابق)

في الغالب تعمل لهم تغليف حتى تعمل على جميع الأنظمة ( يعني تستخدم دوال السي القياسية ) . لكن لو كنت تملك خوارزمية أفضل يمكنك مناقشتها ( بعد أن ننتهي من الخطوة الثانية .. specification ) .. أما الجافا فيمكن استخدام الكلاس Math مباشرة .. لانه يوفر نفس الدوال بنفس الاسم ومغلفة بشكل جميل .. و على جميع الانظمة .. لذلك لاداعي لوجود نسخة من الكلاس Math في الجافا .

اقتباس
لا احبذ موضوع ان كل الأنواع الرياضيه ان تكون generic و السبب فى ذلك عندما نبدأ فى التكلم عن محرك الفيزياء و خصوصا الفئه الخاصه بالـ collision detection سنحتاج للتعامل مع المتجهات و هذا سيؤدى بنا لجعل اغلب الدوال generic و بهذا يصبح المحرك بأكمله داخل ملفات header.

لايوجد مشكلة .. نضع Vector2D ككلاس Generic .. ونعرف نسخة خاصة منه كـ float :

typedef Vector2D<float> Vector2Df

لاستخدامها متى ما أردنا ...

اقتباس
row-major order لإنه هو الإفتراضى فى التعامل مع المصفوفات بشكل عام فى الرياضيات

هذا صوت للـ row-major :) .. بانتظار بقية الاخوة ..

رأيي هو الحياد في هذه المسألة .. لان كل طريقة لها ميزتها .. لذلك لامانع من استخدام أي طريقة مع أني تعوّدت على column-major ..

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#85

أفضل ال column-major لتوافقه مع OpenGL التي تستخدم في الجافا

اقتباس
أول سؤال : ماهو نظام matrix الذي سنعتمده ؟

أفضل ال column-major لتوافقه مع OpenGL التي تستخدم في الجافا

اقتباس
الطريقة متبعة في OpenGL و Ogre وكثير من الكتب المتخصصة في برمجة الرسوميات . كما أن كثيراً من الجامعات تعتمد على هذا الأسلوب في تدريس المادة

الايميل غير صحيح

يرجى تصحيح الايميل برسالة لأحد مدراء المنتدى

#86
اقتباس
الطريقة السابقة مستخدمة في Direct3D .. و irrlicht وبعض المكتبات الاخرى .

و هو يتكلم على اسلوب الصف الرئيسى بالإضافه إلى وجود العديد من الكتب المتخصصه و التى تتعامل مع المصفوفات بهذا الإسلوب منها Graphics Programming with DirectX 9 و Game Physics و غيرهم :)

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 1 أكتوبر 2009 في 14:39

مدونتي: C++ Tips and Tricks

#87

هذا هو الشكل المبدئى للمصفوفه

 

[color= #0000ff;]template [color= #000000;]<[color= #0000ff;]typename T[color= #000000;]>

[color= #0000ff;]class Matrix3x3

[color= #000000;]{

[color= #0000ff;]public[color= #000000;]:

	T m11, m12, m13

	  m21, m22, m23

	  m31, m32, m33;

 

	Matrix3x3[color= #000000;]<T[color= #000000;]>[color= #000000;]([color= #000000;]);

	Matrix3x3[color= #000000;]<T[color= #000000;]>[color= #000000;](T _11, T _12, T _13

		     T _21, T _22, T _23

		     T _31, T _32, T _33[color= #000000;]);

	Matrix3x3[color= #000000;]<T[color= #000000;]>[color= #000000;](T[color= #000000;][[color= #000000;]][color= #000000;][[color= #000000;]] elements[color= #000000;]);

 

	Matrix3x3[color= #000000;]<T[color= #000000;]> add      [color= #000000;](Matrix3x3[color= #000000;]<T[color= #000000;]> m[color= #000000;]);

	Matrix3x3[color= #000000;]<T[color= #000000;]> subtract [color= #000000;](Matrix3x3[color= #000000;]<T[color= #000000;]> m[color= #000000;]);

	Matrix3x3[color= #000000;]<T[color= #000000;]> muliply  [color= #000000;](Matrix3x3[color= #000000;]<T[color= #000000;]> m[color= #000000;]);

 

	Vector2D[color= #000000;]<T[color= #000000;]> muliply [color= #000000;](Vector2D[color= #000000;]<T[color= #000000;]> m[color= #000000;]);

 

	[color= #0000ff;]void Determined[color= #000000;]([color= #000000;]);

	[color= #0000ff;]void Transpose[color= #000000;]([color= #000000;]);

 

	[color= #0000ff;]void Translate[color= #000000;](T xPos, T yPos[color= #000000;]);

 

	[color= #0000ff;]void RotateX[color= #000000;]([color= #0000ff;]float angle[color= #000000;]);

	[color= #0000ff;]void RotateY[color= #000000;]([color= #0000ff;]float angle[color= #000000;]);

	[color= #0000ff;]void Rotate [color= #000000;]([color= #0000ff;]float Yaw, [color= #0000ff;]float Pitch[color= #000000;]);

 

	Matrix3x3[color= #000000;]<T[color= #000000;]> getIdentity[color= #000000;]([color= #000000;]);

 

	oprtator T[color= #000000;]**[color= #000000;]([color= #000000;]); 

[color= #000000;]};

مدونتي: C++ Tips and Tricks

#88

السلام عليكــم ورحمـة الله وبركاتــه ،،

هناك سؤال محير

إذا كان هناك طريقتان لنظام المصفوفات وكل طريقة لها مستخدميها وكتبها

فما الفرق الجوهري بينهما (غير طريقة الحساب) ؟

وهل يمكن عمل فئة تدعم الإثنين معاً؟

وهل يؤثر هذا ألإختيار على طريقة بناء المحرك ؟

أسف لكثرة الاسئلة ولكن هذا لكي أفهم أكثر

الايميل غير صحيح

يرجى تصحيح الايميل برسالة لأحد مدراء المنتدى

#89
اقتباس
إذا كان هناك طريقتان لنظام المصفوفات وكل طريقة لها مستخدميها وكتبها

فما الفرق الجوهري بينهما (غير طريقة الحساب) ؟

وهل يمكن عمل فئة تدعم الإثنين معاً؟

وهل يؤثر هذا ألإختيار على طريقة بناء المحرك ؟

لايوجد تناقض .. الفرق فقط في ترتيب عناصر المصفوفة .. فهي في الاخير مصفوفة لها نفس طريقة لاضرب والجمع .. الخ .

الفرق سيكون في ترتيب عناصر المصفوفة في Translate و Scale و Rotate ..

تستطيع أن تقرأ أي مقالة .. لتعرف كيف يتم ترتيب العناصر .

الفرق الاخر هو في طريقة الضرب .

بعد أن تجري العمليات .. يمكن بعدها ان تتنقل من طريقة الى أخرى عن طريق transpose ( منقول المصفوفة ) .

هناك مثلا مكتبات فيزيائية غير متوافقة مع opengl .. لذلك يجب أن نطبق منقول المصفوفة .. حتى تتوافق .

طبعا لن يؤثر على بناء المحرك .. كثيرا .. لكن ستختلف طريقة الضرب .

من اليمين لليسار بالنسبة column-major .

و من اليسار الى اليمين بالنسبة لـ row-major .

ويجب أن تكون الطريقة موحدة في المحرك سواء في الجافا أو السي بلس .

اذا أردنا استيراد المصفوفة في OpenGL باستخدام glLoadMatrix .. فقط نقوم بتطبيق منقول المصفوفة حتى تعمل المصفوفة .

oprtator T**();

ماذا تقصد بها أخ محمد :) ،

بالنسبة للـ RotateX و RotateY .. لايمكن تطبيقها في عالم ثنائي البعد .. لذلك يجب أن تحذف .

في العالم الثنائي البعد ليس أمامنا الا RotateZ ( دوران حول نقطة ) ، لذلك نسمّيها Rotate للتسهيل .

لي رجعة مع كلاس Matrix الذي طرحه الاخ محمد

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#90
oprtator T**();

هى داله اختياريه و تعود بمصفوفه ثنائية الابعاد البعد الأول يمثل عدد الصفوف و البعد الثانى يمثل عناصر كل صف

اقتباس
بالنسبة للـ RotateX و RotateY .. لايمكن تطبيقها في عالم ثنائي البعد .. لذلك يجب أن تحذف .

اعتقدت انه يمكن محاولة تدوير الصور (لا توجد كائنات هنا) حول اى من المحورين

مدونتي: C++ Tips and Tricks

#91
اقتباس
أول سؤال : ماهو نظام matrix الذي سنعتمده ؟

هناك نظامين :

column-major order : وهو يقوم على ترتيب عناصر المصفوفة بشكل عمودي - هكذا :

بما أني لم أسمع بال Row-Major سابقا فإذا أنا أصوت لنظام ال column وخصوصا أن ال Xna تدعمه..

اقتباس
في الغالب تعمل لهم تغليف حتى تعمل على جميع الأنظمة ( يعني تستخدم دوال السي القياسية ) . لكن لو كنت تملك خوارزمية أفضل يمكنك مناقشتها ( بعد أن ننتهي من الخطوة الثانية .. specification ) .. أما الجافا فيمكن استخدام الكلاس Math مباشرة .. لانه يوفر نفس الدوال بنفس الاسم ومغلفة بشكل جميل .. و على جميع الانظمة .. لذلك لاداعي لوجود نسخة من الكلاس Math في الجافا .

طبعا نفس الكلام ينطبق على ال C#؟؟

بالنسبة لل matrix يبدو أنك نسيت ال Scale

void Scale(T Sx, T Sy);

هنالك أيضا بعض العمليات الآخرى مثل ال Shear لا أدري إن كان لها مكان في هذه النسخة؟؟

Matrix3x3<T> add	  (Matrix3x3<T> m);
	Matrix3x3<T> subtract (Matrix3x3<T> m);

هل هنالك حاجة لوجود هاتين الدالتين، (ذكروني لأني يبدو أني نسيت ال Computer Graphics) ؟

#92

هناك بعض الغموض بالنسبة لدوال التحويل المكتوبات.

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

لذلك إذا أردنا أن نقوم بعمل تحويل لنقطة معينة سيكون لدينا كود مثل التالي

Matrix mx= new Matrix();
Vector2D v=new Vector(10,20);
Vector2D newV = Matrix.Translate(v, 15,15);

أم تريد مثلا أن يتم إنشاء المصفوفة و بعدها و من خلال أحد دوال التحويل يتم تعبئة المتغيرات و من ثم يتم إستخدام دالة الضرب؟؟

كالتاللي

Vector2D v=new Vector(10,20);
Matrix mx= new Matrix();
mx.Translate( 15,15);

Vector2D newV = mx.Multiply(v);

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

#93

السلام عليكــم ورحمـة الله وبركاتــه ،،

انا اصوت للطريقة row-major order

#94

ملاحظات /

@ getIdentity :

لماذا تعيد مصفوفة ؟ ، أقترح أن يكون اسمه identity أو setIdentity .. لتحوّل المصفوفة الحالية الى مصفوفة الوحدة .

@Translate :

كيف ستعمل ؟

أقترح التالي ، يوجد لكل عملية دالتين :

Translate - setTranslate

- الدالة : Translate تقوم بالتالي :

- انشاء مصفوفة ازاحة جديدة .

- ضرب مصفوفة الازاحة بالمصفوفة الحالية وتخزينها في مصفوفة جديدة X .

- المصفوفة الحالية تساوي المصفوفة الجديدة X .

- الدالة : setTranslate تقوم بالتالي :

- انشاء مصفوفة ازاحة جديدة .

- المصفوفة الحالية تساوي المصفوفة الجديدة . ( أي كأننا عملنا identity ثم عملنا ازاحة ) .

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

Matrix m ... 
m.identity();
m.translate( x,y);
m.rotate( 45 );
m.scale(2,2);

graphics.loadMatrix( m );

أما الطريقة الأخرى فهي أكثر تنظيم ، لكنها تحتاج لانشاء عدة كلاسات .. تقريبا :

Matrix m1;
Matrix m2;
Matrix m3;
m1.setTranslate(x,y);
m2.setRoatate(45);
m3.setScale(2,2);
Matrix result  = m1 * m2 * m3;
graphics->loadMatrix(m3);

لذلك تصبح Matrix بعد التعديلات المقترحة :

  1.  
  2.  
  3. class Matrix3x3 <T>
  4. {
  5. public:
  6. T m11, m12, m13
  7. m21, m22, m23
  8. m31, m32, m33;
  9.  
  10. Matrix3x3<T>();
  11. Matrix3x3<T>(T _11, T _12, T _13
  12. T _21, T _22, T _23
  13. T _31, T _32, T _33);
  14. Matrix3x3<T>(T[][] elements);
  15.  
  16. Matrix3x3<T> add (Matrix3x3<T> m);
  17. Matrix3x3<T> subtract (Matrix3x3<T> m);
  18. Matrix3x3<T> muliply (Matrix3x3<T> m);
  19.  
  20. Vector2D<T> muliply (Vector2D<T> m);
  21.  
  22. void Determined();
  23. void Transpose();
  24.  
  25. void setTranslate(T xPos, T yPos);
  26. void Translate(T xPos, T yPos);
  27.  
  28. void Rotate (float angle);
  29. void setRotate (float angle);
  30.  
  31. void Scale(T xScale,T yScale);
  32. void setScale(T xScale,T yScale);
  33.  
  34. Matrix3x3<T> getIdentity();
  35.  
  36. oprtator T**();
  37. };
  38.  
  39.  

طبعا هذه مجرد اقتراحات .. وبانتظار الاقتراحات الأفضل .

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#95

موضوع المصفوفات مع الـ 2D هو مزعج بالنسبه لى حيث انى اعرف كيف تتم الأمور داخل الـ 3D و لا اعرف كيف ستتم داخل الـ 2D.

لإنه كما اعتقد ان الـ 2D سيكون عبارة عن مجموعه من الطبقات فوق بعضها كل واحده مرسوم عليها شئ معين. الأمر مربك صراحة و لا اعرف كيف ستكون المصفوفه لهذا النظام هذا إذا كانت تحتاجه بمعنى داخل الـ 3D نحتاج المصفوفات لحساب حجم الكائن و موقعه بالنسبه للعبه و غيرها من العمليات و لكن فى الـ 2D ماذا سنستخدمها و ما العمليات التى سنحتاج إليها فإذا قلنا تدوير ماذا سندير هل سندير صورة ؟؟ و إذا قلنا تحجيم فإنه عند تحجيم صورة تفقد خصائصها إلا لو كان التحجيم ثابت او انها vector (نوع من انواع الصور).

موضوع المصفوفات داخل المحرك مربك قليلا فأرجو توضيح فاءدتها حتى اعرف او نعرف ما العمليات التى سنحتاج إليها فيها.

مدونتي: C++ Tips and Tricks

#96

المعذرة أخ خلدون ، لم أنتبه لمشاركتك :

اقتباس
بما أني لم أسمع بال Row-Major سابقا فإذا أنا أصوت لنظام ال column وخصوصا أن ال Xna تدعمه..

هل أنت متأكد ؟ يبدو لي أنها تتبع نفس نظام Direct3D أي Row-Major .. ومش متأكد طبعا .

اقتباس
طبعا نفس الكلام ينطبق على ال C#؟؟

صحيح ..

اقتباس
هنالك أيضا بعض العمليات الآخرى مثل ال Shear لا أدري إن كان لها مكان في هذه النسخة؟؟

لا أعرف .. لكن هي ليست ذات أهمية في برمجة الالعاب على ما أظن ! هذا رأيي .

اقتباس
هل هنالك حاجة لوجود هاتين الدالتين، (ذكروني لأني يبدو أني نسيت ال Computer Graphics) ؟

في الغالب لن نحتاجهما .. لكن هي عمليات أساسية وسهلة وبسيطة لذلك تجدها في كل مكان .

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

سأفرض أنك قرأت ردّي السابق وسأبني عليه .

الدالتين translate و setTranslate لاتقومان باعادة متجه .. انما تغيران المصفوفة الحالية الى مصفوفة ازاحة .

الدالة muliply هي التي تقوم بضرب المتجه بالمصفوفة وتعيد المتجه بعد التعديل .

طبعا الدالة muliply ستكون في السي بلس على شكل operator (* ) .. ولكن يمكن أن نسميها أيضا :

transformVector لو أحببتم ذلك حتى تكون واضحة أكثر بحيث يكون في السي بلس operators و transformVector

- سؤال :

هل هناك فرق بين عملية ضرب نقطة في مصفوفة أو متجه في مصفوفة .. transformVector أو transformPoint .

- سؤال اخر :

ما رأيكم .. هل نحن بطيئين في الحركة أو مسرعين :D .. هل هناك شيء غير مفهوم .. هل هناك اعتراض على أي شيء ، ؟

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#97
اقتباس
هل هناك شيء غير مفهوم .. هل هناك اعتراض على أي شيء ، ؟

لم يجاوب احد على تساؤلاتى ؟ post-135620-1254438170_thumb.gif

مدونتي: C++ Tips and Tricks

#98

:D .

اقتباس
موضوع المصفوفات مع الـ 2D هو مزعج بالنسبه لى حيث انى اعرف كيف تتم الأمور داخل الـ 3D و لا اعرف كيف ستتم داخل الـ 2D.

لإنه كما اعتقد ان الـ 2D سيكون عبارة عن مجموعه من الطبقات فوق بعضها كل واحده مرسوم عليها شئ معين. الأمر مربك صراحة و لا اعرف كيف ستكون المصفوفه لهذا النظام هذا إذا كانت تحتاجه بمعنى داخل الـ 3D نحتاج المصفوفات لحساب حجم الكائن و موقعه بالنسبه للعبه و غيرها من العمليات و لكن فى الـ 2D ماذا سنستخدمها و ما العمليات التى سنحتاج إليها فإذا قلنا تدوير ماذا سندير هل سندير صورة ؟؟ و إذا قلنا تحجيم فإنه عند تحجيم صورة تفقد خصائصها إلا لو كان التحجيم ثابت او انها vector (نوع من انواع الصور).

موضوع المصفوفات داخل المحرك مربك قليلا فأرجو توضيح فاءدتها حتى اعرف او نعرف ما العمليات التى سنحتاج إليها فيها.

جيد ..

أولا لنتفق على شيء :

OpenGL و Direct3D و أي مكتبة رسومية ستجد أنه لتحرك شيء أو تقوم بتدويره أو تحجيمه .. ستحتاج الى مصفوفة للقيام بذلك .. تسهيلاً للعمل . سواء كان البعد ثنائي أو ثلاثي لايهم .

- المصفوفات في الألعاب الثنائية الأبعاد مثلها مثل المصفوفات الثنائية الأبعاد باستثناء حذف البعد الثالث Z .

- حتى نقوم بازاحة شكل ما ( صورة أو أي شيء ) .. نستخدم translate في بعدين .. ازاحة على المحور السيني وازاحة على المحور الصادي .

post-42837-1254443778_thumb.png

- قد تسأل سؤال .. يمكننا الاستغناء عن المصفوفة .. والتحريك بطريقة عادية مثل :

player.x = player .x + 1;

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

- عندما نستخدم Rotate ، فاننا ندير شكل ثنائي البعد حول نقطة .. كيف نقوم بذلك ؟

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

post-42837-1254443859_thumb.png

- عندما نستخدم Scale فاننا نقوم بتحجيم الشكل الثنائي البعد ( أي أننا نكبّر أبعاده أو نصغرها ) ، هل سيتشوّه الشكل .. الجواب :

اذا كانت صورة ( أي اكساء ) .. فانه حتماً سيحصل شيء من التشوّه .. لكن باستخدام تكبير أو تصغير بمقدار مناسب لن يحدث هذا التشوّه ..

طبعا هنا لايوجد شيء اسمه صورة vector في محركات الألعاب .. نحن نستخدم صورة عادية Raster Image

عموما .. نحن نسمح بهذه الخدمة .. فمن أراد أن يستخدمها فليستخدمها .

post-42837-1254443876_thumb.png

طيب .. السؤال .. هل كل شيء سيعتمد على مصفوفة ؟

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

كيف سنستخدم المصفوفة .. قد نكتب شيء كهذا :

while( run == true ) 
{
Matrix m1 ...
m1.setTranslate( x , y );
Matrix m2 ....
m2.translate(x2,y2);
m2.rotate(45);

gfx.loadMatrix( m1)
gfx.drawShape( color , ... )// سيتم ازاحة الشكل

gfx.loadMatrix( m2);
gfx.drawShape(color2 ,...);// سيتم ازاحة وتدوير الشكل 

}

- اذا كنت تعرف تستخدم المصفوفات في عالم ثلاثي البعد .. فبنفس الطريقة ان لم تكن أسهل .. في العالم الثنائي البعد .

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

http://www.box2d.org/

تنبيه :

عندما أقول " صورة " .. فانه في محرك الألعاب الصورة هي اكساء Texture ، ولها احداثياث اكساء مرتبطة برؤوس الشكل ( مستطيل مثلا ) ، فبالتالي عندما نحرك أو نقوم بتدوير رؤوس المستطيل ستجد المستطيل المكسو بالصورة تفاعل معك .

أي أننا لانقوم بتحريك أو تدوير بكسلات الصورة .

تم تعديل هذه المشاركة بواسطة الشمري في 2 أكتوبر 2009 في 03:42

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#99

يبدو أن الملل أصاب بعض الاخوة .. لم نعد نراهم :D .

لذلك سيكون لدينا يومين تقريبا لاضافة في أي كلاس .. ( أو أي تعديل أو اقتراح ) .. بعد أن ننتهي منها .. سنبدأ في implementation ان شاء الله .

هل المدة كافية .. مارأيكم ؟

وبالمرّة .. نقوم بتوصيف للكلاس الذي يقوم بتوليد عدد عشوائي Random .

وهذا اقتراحي :

class Random

{

public :

Random( )

Random ( int seed)

void setSeed( [iN] int seed )

int generateInteger([iN] int min , [in] int max)

float generateFloat([iN] float min , [in] float max)

private:

int seed

}

الدالة الاولى : تحدد البذرة seed ،

الدالة الثانية : لتوليد عدد عشوائي صحيح يقع بين min و max .

الدالة الثالثة : لتوليد عدد عشوائي كسري يقع بين min و max .

ملاحظة : الكلاس هذا ممكن يحوي على member أخر غير seed .. هذا يعتمد على implementation .. المهم أن يكون لدينا نفس الثلاث دوال Methods .

تم تعديل هذه المشاركة بواسطة الشمري في 2 أكتوبر 2009 في 04:05

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#100

شكرا اخى عبد الله على اجابتك على الأسئله و جزاك الله خيرا

اقتباس
نقوم بتوصيف للكلاس الذي يقوم بتوليد عدد عشوائي Random .

النسخه التى صنعتها جميله و لكن لماذا لم تعتمد فيها على الـ Templates :P . ايضا ما المقصود بـ seed ؟

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 2 أكتوبر 2009 في 05:12

مدونتي: C++ Tips and Tricks

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…