السلام عليكم ..
كيف الصحة إخواني ..
و الله كثير مشتاق للمنتدى و لأعضاء المنتدى ..
كنا منهمكين بالامتحانات ،، و الحمد لله عدت على خير !!
المهم ..
هذا درس على الماشي للمبتدئين
لتحويل شكل من الطبيعة الى شكل مرسوم على الشاشة ..
هناك عدة مراحل لهذه العملية
1- Modeling
إعطاء إحداثيات طبيعية للشكل .
2- Viewing Transformation
تحويل الإحداثيات الى قياسية منتظمة (كارتيزية) .
3- Projection
تحويل الإحداثيات الثلاثية الى ثنائية بالاعتماد على البعد الثالث z .
4- Display
عملية العرض على الشاشة .
سأحاول في هذا المقال شرح العملية الثالثة ، و هي عملية الإسقاط projection
ما معنى الاسقاط ؟؟
الأشكال التي تظهر على شاشة الحاسبة والتي تبدو كشكل مجسم 3 D (مثلا في الألعاب و غيرها) ، كيف ظهرت ؟؟
الشاشة (والتي نعتبرها السطح العارض) هي ثنائية البعد 2 D ، فكيف تبدو الأشكال عليها وكأنها ثلاثية البعد ..
تتم هذه العملية وفق قوانين خاصة ..
يعني أي شكل لديك في الطبيعة (منتظم) مثلا مكعب أو كرة .. كيف تقوم بتحويله (يدويا) إلى شكل ليبدو ثلاثي البعد على الحاسبة ..
عملية سهلة جدا ..
مجرد تطبيق قوانين .. هناك اكثر من نوع من الإسقاط وكل نوع له قوانينه الخاصة به .
أنواع الإسقاط
1- Parallel Proj. 2- Perspective Proj.
النوع الاول (المتوازي) ، عملية الإسقاط تتم باستخدام خطوط متوازية ، اما في النوع الثاني ، عملية الاسقاط تتم بأفتراض ان هناك نقطة تقع خلف السطح العارض و خطوط الشكل تتقاطع في هذه النقطة .
انواع الاسقاط المتوازي :
Parallel Proj. types : a- Orthographics
اذا كانت الخطوط التي تقطع الشكل متعامدة على السطح العارض سيظهر فقط وجهه واحد ، في هذا النوع يهمل البعد الثالث z أي النقطة x,y,z ستتحول الى x,y
b- Oblique
الخطوط الممتدة من الشكل و التي تقطع السطح العارض تكون مائلة بزاوية الفا ، ايضا ستكون هناك زاوية اخرى هي زاوية ميلان الشكل عن خط الافق ويرمز لها فاي
..
يمكن الامر مش واضح !!!
ما يهم في الامر هو معرفة القوانين ..
لتحويل أي شكل من 3D الى 2D ، ممكن تطبيق القوانين التالية (قوانين oblique)
xp = x + z * (cos f/ tan alpha) yp = y + z * (cos f/ tan alpha )
افضل قيم تعطى للزوايا :
alpha= 45 or 63.4 f = 30 or 45
خلونا ناخذ مثال بسيط (بلغة C) لنطبق هذه الطريقة ،
سنقوم برسم مكعب ،
المكعب يحوي على ثمان نقاط تصل بينها خطوط ،
اذا ستكون هناك 8 قيم لكل من x,y,z
سنعرف مصفوفات لهذه القيم كالأتي :
int x[8],y[8],z[8]; x[0]= x[2]= x[4]= x[6]=50; x[1]= x[3]= x[5]= x[7]=150; y[0]= y[1]= y[4]= y[5]=50; y[2]= y[3]= y[6]= y[7]=150; z[0]= z[1]= z[2]= z[3]=50; z[4]= z[5]= z[6]= z[7]=150;
هنا قمت بأعطاء قيم النقاط مباشرةً (يجب ان تكون دقيق في هذه العملية و تحسب قيم النقاط بصورة صحيحة ، يعني للمكعب مثلا .. في الوجه الامامي للمكعب ستتساوى قيم z الاربعة مثلا z1 و في الوجه الخلفي ايضا ستتساوى قيم z الاربعة و ستكون مثلا z1+100 ، مجموع النقاط 8 ، وفي الجانب الايسر من المكعب ستتساوى قيم x الاربعة مثلا x1 و للجانب الايمن ستتساوى قيم x الاربعة وستكون مثلا x1+100 ، وفي السطح العلوي من المكعب ستتساوى قيم y الاربعة مثلا y1 و للسطح السفلي ستتساوى قيم y الاربعة وستكون مثلا y1+100 ، واااااااضح )
ثم بعد ذلك نقوم بتطبيق القوانين على هذه النقاط كالأتي :
float A= 45*M_PI/180;
for(int i=0;i<8;i++)
{
x=x+z*1/tan(A)*cos(A);
y=y+z*1/tan(A)*sin(A);
}خلص .. خلصنا .. بقي فقط عملية رسم الشكل (وصل النقاط بخطوط .. بصورة صحيحة )
line(x[0],y[0],x[1],y[1]); line(x[1],y[1],x[3],y[3]); line(x[3],y[3],x[2],y[2]); line(x[2],y[2],x[0],y[0]); line(x[4],y[4],x[5],y[5]); line(x[5],y[5],x[7],y[7]); line(x[7],y[7],x[6],y[6]); line(x[6],y[6],x[4],y[4]); line(x[0],y[0],x[4],y[4]); line(x[1],y[1],x[5],y[5]); line(x[2],y[2],x[6],y[6]); line(x[3],y[3],x[7],y[7]);
اعتقد عملية سهلة و بسيطة و ممتعة ..
طيب لو اردنا رسم هرم !!
نفس المكعب مع اختلاف واحد وهو ان الهرم لديه خمس نقاط بدل الثمانية ، فقققققققط .. لكن انتبه لعملية اعطاء قيم النقاط حيث ستكون نقطة رأس الهرم هي في منتصف المسافة بالنسبة لـ x z (مقارنة مع قيم قاعدة الهرم)
** من خصائص هذه الطريقة ان الشكل يحافظ على ابعادة والنسب الموجودة بالشكل .
النوع الثاني من الاسقاط وهو perspective
يفترض وجود نقطة تدعى center of proj. تقع خلف السطح العارض تبعد عنه بقيمة معينة يرمز لها ب d حيث كلما قلت d صغر الشكل و العكس صحيح .. وجميع الخطوط الممتدة من الشكل بأتجاه السطح العارض تلتقي عند هذه النقطة ..
طيب ماذا سيحصل لو كانت d=0 أي نقطة التقاء الخطوط تقع على الشكل العارض .. هاي عليكم !!!!!
القوانين :
xp= x*(d/(d+z)) yp= y*(d/(d+z))
ايضا تطبق بنفس الطريقة التي في الاعلى ..
مثلا لرسم شكل Tetrahedron (هرم ذو قاعدة مثلثة )
سيكون لدينا اربع نقاط فقط ..
int x[4],y[4],z[4];
x[0]= 100; x[1]=200; x[2]= x[3]=150;
y[0]= y[1]= y[2]= 200;y[3]=50;
z[0]= z[1]=100; z[2]=150; z[3]=125;
int d=350;
for(int i=0;i<4;i++)
{
x=x*(d/(float)(d+z));
y=y*(d/(float)(d+z));
}
line(x[0],y[0],x[1],y[1]);
line(x[1],y[1],x[2],y[2]);
line(x[2],y[2],x[0],y[0]);
line(x[0],y[0],x[3],y[3]);
line(x[1],y[1],x[3],y[3]);
line(x[2],y[2],x[3],y[3]);** في هذه الطريقة ، الشكل لا يحافظ على نسبة لكنه يكون اقرب للشكل الواقعي ..
نفذ الطريقتين على شكل واحد .. و انت تعرف الفرق ..
طيب من يقدر يفكر بكيفية رسم اسطوانة او مخروط ..
سهلة .. ولو في متابعة سأضع الحل في مشاركتي القادمة ..
المهم ..
في الدرس القادم سأحاول ان اشرح 3 D Transformation
و اعذرونا على التقصير .. و ارجو التصحيح من اصحاب الخبرة ..
و السلام عليكم ..
