8.5 الرسم ثنائي الأبعاد كتاب لينكس الشامل >>

8.5 الرسم ثنائي الأبعاد

8.5.1 مقدمة

يتم التعبير عن الرسوم على الشاشة التي هي نقاط مضيئة تسمى بيكسلات pixles مصطفة بجانب بعضها البعض بمصفوفة في الذاكرة الخاصة ببطاقة العرض (كرت الشاشة) تسمى framebuffer هذه المصفوفة هي عبارة عن أرقام كما في الشكل


كل رقم يمثل لون معين وليس بالضرورة أن يكون 1 بايت كما سنعرف لاحقا كيف نمثل الألوان

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

tipتلميح

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

تقوم بطاقة العرض بإعادة رسم ما في هذه المصفوفة تلقائياً خلال فترات معينة تسمى refresh rate وغالباً ما تكون 60-70 fps أي frame per second شاشة لكل الثانية وكما تعلم فإن المصفوفة لها حجم هو عدد الصفوف × عدد الأعمدة ونفس الشيء هنا لدينا دقة العرض resolution وهي عدد النقاط في السطر الواحد × عدد الأسطر وكلما كان العدد أكبر كانت الصورة أوضح وبحاجة إلى المزيد من الذاكرة والمزيد من العمليات الحسابية في التعامل معها. إذا كان لدينا دقة بمقدار 640×480 نستطيع رسم النقاط من 0 إلى 639 وعلى الأسطر من 0 إلى 479 ونقول بأن لدينا مجال عرض viewport من صفر ، صفر وبعرض 640 وبارتفاع 480

8.5.2 تمثيل الألوان

المصفوفة التي تحدثنا عنها تحتوي أرقاماً هذه الأرقام تمثل ألواناً وهناك أكثر من طريقة لتمثيل هذه الألوان منها طريقة الألوان الحقيقية أو RGB وتعني أننا نعطي مقدار الأحمر ومقدار الأخضر ومقدار الأزرق ويكون اللون ناتجح مزج الأضواء بتلك الألوان وقد نحدد العمق اللوني color depth مثلا ب 24-بت (أي 3 بايت) فيكون لكل لون أساسي رمز من 8-بت أي من 0-255 ونعبر في البرمجة عنها بالنظام الست-عشري فتكون من صفر إلى ff مثلا الأبيض في html بالشكل التالي #ffffff أو في لغة C قد نستخدم int حيث أنه 32-بت نستخدم أول 24-بت منها وذلك عن طريق الإزاحة مثلا الأبيض

0xff+ (0xff<<8)+ (0xff<<16)= 0xffffff
لا يفيض كل لون على القيمة العليا نستخدم دالة AND مع أقصى قيمة مسموحة وبهذا نحصل على مانريد
 c1=((r1 & 255)<<8)+((g1 & 255)<<16)+(b1 & 255)

وهناك أطوار حقيقية غير ال 24-بت مثل 32-بت و 15-بت وهذا الأخير يكون لكل لون أساسي من أحمر وأخصر وأزرق 5-بت وهو غير قياسي ولا تدعمه معظم كررت الشاشة أما 16-بت فهو أكثر توفراً وهو المفضل لدي بشكل عام حيث نخصص للأحمر والأزرق 5-بت أما الأخضر 6-بت وسبب سرعته أنه يوفر 8-بت لكل نقطة مقارنة بطور 24-بت.

tipتلميح

في مكتبة openGL نعبر عن اللون بثلاث أعداد نسبية float قيمة كل واحد تقع بين الصفر والواحد فالأبيض هو float myWhite[]={1.0,1.0,1.0};

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

tipتلميح

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

ولكن لأسباب اقتصادية تم اضافة اللون الأسود لهذا النظام فاصبح اسمه CYMK. والمعادلة للتحويل من CYMK إلى RGB هي
 r=255-(k+c); if (r<0) r=0;
 g=255-(k+m); if (g<0) g=0;
 b=255-(k+y); if (b<0) b=0;
وللتحويل العكسي من RGB إلى CYMK:
 k=255-max(r,g,b);
 c=255-k-r ;
 m=255-k-g ;
 y=255-k-b ;

والطريقة الأخرى هي طريقة جدول الألوان pallete وهي طريقة مستخدمة في عمق لوني 8-بت (أي 1 بايت لكل نقطة) فما دون حيث نخزن جدول ألوان في مكان منفصل يحتوي على كيفة تفسير الأرقام من 0-255 بألوان حقيقية وهي طريقة أكثر توفيرا في الذاكرة وسرعة حيث كل نقطة نمثلها بواحد بايت فقط وهي أقدم من الألوان الحقيقية

tipتلميح

تدعم بطاقات العرض vga كثافة نقطية 640x480 مع 4-بت و 320x200 مع 8-بت لهذا فهذه الأخيرة كانت تستخدم بشكل واسع في الألعاب

8.5.3 الذاكرة المزدوجة double buffer

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


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

ولكن ماذا لو أردنا أن نرسم صورة يأخذ توليدها فترة طويلة وتولد على مراحل مثلا رسم مربع (بيت) ثم رسم مستطيل(باب البيت) ولا نريد أن تلحظ العين رسم هذا ثم هذا بل ترى النتيجة النهائية فقط أو مثلا في الصور لمتحركة نرسم ثم نمسح الشاشة ثم نرسم من جديد ولكن لا نريد للعين أن تلاحظ اختفاء الصورة وضهورها بل ترى حركة لهذا نستخدم double buffer والفكرة بسيطة نرسم على ذاكرة مستقلة غير التي تظهر على الشاشة على دفعات وعلى مهل وتأني (وفي هذا الوقت تكون الشاشة تعرض الصورة القديمة) ثم ننقل النتيجة النهائية إلى إلى ذاكرة الشاشة فتظهر وكأنها تحركت بسلاسة ورسمت في بسرعة آنية دون أن تمحى وتظهر أي دون أن ترمش

8.5.4 ذاكرة بطاقة العرض

تستخدم هذه الذاكرة في تخزن مصفوفة ال frame buffer وتخزين جدول ألوان واحد (يكون محجوز ولا يستخدم إذا كنا في طور الألوان الحقيقية وهو لا يحسب جزء من ذاكرة الشاشة ) فإذا قلنا أنك تملك بطاقة عرض 1MB (أي 1048576) فإن هذه البطاقة قد تتمكن من دعم كثافة 800x600 ب 16-بت(2 بايت) لأن 800*600*2= 960000 أقل من 1 MB بعمق 24-بت فإن ذاكرة العرض لن تكفي.

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

8.5.5 قلب الصفحة page flipping

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

8.5.6 أساسيات الرسم

عرفنا أن رسم النقطة يكون بوضع لونها في الذاكرة الخاصة بذلك ولرسم خط نقوم برسم جميع النقاط ذات الإحداثيات الصيحيحة (غير الكسرية) الموجودة على الخط وأيضا النقاط التي تصل بينها . وتستخدم طرق رياضية لتحديد هذه النقاط بشكل متسلسل أي ايجاد النقطة إذا علمت النقطة التي قبلها ودون اجراء عملية ضرب فتكون العملية سريعة فنحن لا نستخدم القوانين العادية y=ax+b ولا P=(P2-P1)t+P1 حيث t عدد بين الصفر والواحد و P و P1 و P2 عبارة عن متجه (زوج مرتب) وأعتقد أنه لا مجال لذكر الطريقة هنا

tipتلميح

هذه العمليات لن تقوم أنت بكتابة برنامجها وإنما تقوم بها مكتبة الرسومات مثل OpenGL و Allegro وأنا أعرضها للثقافة

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

الطريقة العادة في الرسم تجعل الخطوط تبدو مكسورة وغير مستقيمة عند التدقيق فيها أو تكبيرها بسبب طبيعة كون المصفوفة تحتوي عدد محدود وصحيح من النقاط لهذا تستخدم في بعض البرامج مثل gimp والمكتبات مثل OpenGL طريقة تسمى anti-alised لجعل الخطوط والرسومات تبدو ملساء smooth وذلك برسم تدرج حولها مثلا إذا رسمت خط أسود على خلفية بيضاء ستضع بعض النقاط الرمادية لتعطيك وهما بأنه الخط مستقيم

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

P(t)=P1.(t)3 +3.P2.(t)2.(1-t) +3.P3.(t).(1-t)2 +P4.(1-t)3

حيث t بين الصفر والواحد و P(t) هي موقع الجسم عند t و P1 و P4 هي نقطة البداية والنهاية أما P2 و P3 فهي نقطتا الدليل وإذا لم تكن تألف هذه الصيغ هذه التفاصيل

x(t)=x1.(t)3 +3x2.(t)2.(1-t) +3x3.(t).(1-t)2 +x4.(1-t)3
y(t)=y1.(t)3 +3y2.(t)2.(1-t) +3y3.(t).(1-t)2 +y4.(1-t)3
z(t)=z1.(t)3 +3z2.(t)2.(1-t) +3z3.(t).(1-t)2 +z4.(1-t)3

8.5.7 طرق تخزين الرسومات

الطريقة الأولى تسمى Bitmap أو Raster Image حيث نخزن طولها وعرضها والعمق اللوني وجدول الألوان إن لزم الأمر ثم نخزن الصورة كما هي الذاكرة كسلسلة من الأرقام تمثل الأرقام الموضوعة في المصفوفة أو نقوم بضغطها فمثلا تتقنية jpeg تقوم بطريقة ضغط فاقدة للجودة أما gif و png فهي تقنيات ضغط غير فاقدة (أو أقل فقداً) إلا أن gif لا تصلح سوى لل 8-بت وهي تقنية بها براءة اختراع حصرية على طريقة التخزين والضغط أما png فهي مفتوحة وتصلح لأي عمق لوني أما أسهل طريقة في البرمجة هي xpm انظر إلى محتويات أي ملف xmp هذه مثلا صورة كتاب لاحظ أنك يمكن أن تضعها داخل كود C بلا مشاكل

/* XPM */
static char * openbook [] = {
"16 16 4 1",
"       c None s None",
".      c black",
"X      c #808080",
"o      c white",
"                ",
"  ..            ",
" .Xo.    ...    ",
" .Xoo. ..oo.    ",
" .Xooo.Xooo...  ",
" .Xooo.oooo.X.  ",
" .Xooo.Xooo.X.  ",
" .Xooo.oooo.X.  ",
" .Xooo.Xooo.X.  ",
" .Xooo.oooo.X.  ",
"  .Xoo.Xoo..X.  ",
"   .Xo.o..ooX.  ",
"    .X..XXXXX.  ",
"    ..X.......  ",
"     ..         ",
"                " };

tipتلميح

لا تعيد اختراع العجلة استخدم المكتبات التي تقوم بفتح الصور التي تريد بدلاً من كتابة ذلك بنفسك

وهناك الطريقة المتجهية vector أي أنك تخزن الإحداثيات والأبعاد وماشابه وعند تحميل الملف تقوم برسمها من هذه المعلومات، انظر إلى أي ملف SVG.

8.5.8 الرسوم الانكسارية Fractals والشفق Chaos

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

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

fractals

لعمل Fractals نحدد نقطة بداية تسمى بذرة seed ثم نحدد وظيفة تسمى المولد generator تزيد من تعقيد الرسمة لتعطي المزيد من التفاصيل. في الشكل المجاور العلوي بدأنا بخط كبذرة ثم حددنا المولد على أن تضع الشكل ثم الشكل مائل 45ْ عكس عقارب الساعة ثم 45ْ مع عقارب الساعة ثم الشكل مجدداً. إذا طبقنا المولد على البذرة نحصل على الشكل الأوسط ثم إذا طبقنا المولد على الشكل الأوسط حصلنا على الشكل الأيمن فإذا طبقنا المولد مرة أخرى حصلنا على الزخرفة المطلوبة (النصف العلوي من اللوحة السابقة) .

fractals

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

هل نظرت إلى صحيفة (أسود وأبيض) بواسطة مكبر؟ ستجد أن كافة تدرجات الرمادي حصلنا عليها من وضع نقاط من الأسود والأبيض بترتيب معين يبدو عشوائي للوهلة الأولى يسمى هذا الشفق chaos. مثل آخر عند عمل تدرج بين عدة ألوان قد تلاحظ عند محدودية العمق اللوني (16-بت أو 8-بت) وجود حدود واضحة بين لونين متجاورين وأن التدريج ليس أملساً (ليس في gimp بل في برامج عادية). لنفرض أنك تمتلك لونين فقط أحمر وأصفر (دون التدرجات) -اخترتهما بسبب التباين الشديد بينهما - والمطلوب أن تحصل على لون برتقالي بنسبة الربع والنصف والثلاثة أرباع بين الأصفر والأحمر. أحد الطرق أن تقرّب ما هو مطلوب في موقع معين (لنرمز للأحمر بالرقم0.0 والأصفر 1.0) ، مثلاً بواسطة a=floor(v+e+0.5) حيث a هي ناتج التقريب و v هي القيمة المطلوب تقريبها و e هي الخطأ التراكمي وهو صفر كبداية ونضيف الفرق بين التقريب a والقيمة المطلوبة v إلى الخطأ e+=v-a وهكذا فإن الخطأ يتراكم حتى يصبح واحداً صحيحاً.

مثلاً لعمل ربع أصفر وثلاثة حمر فإن القيمة المطلوبة هي 0.25 تقريبه صفر (نضع نقطة حمراء) والخطأ 0.25 الآن القيمة والخطأ التراكمي 0.5 تقريبه واحد (نضع نقطة صفراء) والخطأ -0.5 ، القيمة والخطأ -0.25 تقريبه صفر (نضع نقطة حمراء) والخطأ -0.25 ، القيمة والخطأ صفر تقريبه صفر (نضع نقطة حمراء) ، وينتج أربع نقاط الثانية صفراء والباقيات حمر نوزعها في المنطقة التي نريد صبغها بهذا اللون فإذا وضعت في مربع بكثافة نقطية 4×4 ستكون النتيجة خطوط عمودية ومن بعيد قد تخدع العين (خصوصاً عند استخدام ألوان أقل تبايناً). بنفس الطريقة نرسم التدرجين الباقيين (النصف والثلاث أرباع).

chaos

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

مثال آخر إذا كنت تريد أن ترسم تدرج عمودي من الأحمر إلى الأصفر. لنجعل المثال أكثر وضوحاً لنفعل ذلك في دقة منخفضة 16×16 مثلاً حيث سنضع في السطر الأول أصفر والسطر الثاني 15 من 16 أصفر و 1 من 16 أحمر والثالث 14 من 16 أصفر و 3 من 16 أحمر .. وهكذا. يمكنك أن تجرب أن ترسمها بواسطة chaos بمسار عادي a=floor( (y/15) +e+0.5) حيث y من 0 إلى 15 ، لتحصل على الشكل في أقصى اليمين ولكن نلاحظ تراكم نقاط وخطوط في أماكن محددة وغير موزعة بالشكل الصحيح. لتوزيعها استخدم نفس المعادلة chaos ولكن بالسير في المسار المعقد 16×16 الذي تحدثنا عنه في fractals. الشكل السابق على اليمين هو للعادي والمجاور على اليسار للمسار المعقد . أما يمين الشكل المجاور تجد فيه عدد من معادلات chaos بمسار معقد 64×64 بلونين فقط لتعطي أشكال مختلفة. لمزيد من الدقة عليك استعمال تدرجات ألوان أكثر.

chaos with fractal path

بشكل عام لنفرض أن هناك صورة القيمة الفعلية هي v(x,y) فإن الشفق يكون a=floor( v(x,y) +e+0.5) ونتحرك فيه من النقطة (0،0) ثم نسير عبر المسار المعقد ونحدث قيمة الخطأ التراكمي e. كما يمكن عمل ثلاث قيم وثلاث أخطاء واحدة لكل لون في طور الألوان الحقيقية RGB.


<< السابق كتاب لينكس الشامل التالي >>