خوارزمية كوهين-سوذرلاند

في مجال رسومات الحاسوب ، تُعد خوارزمية كوهين-ساذرلاند خوارزمية تُستخدم لقص الخطوط . تقسم هذه الخوارزمية مساحة ثنائية الأبعاد إلى 9 مناطق، ثم تحدد بكفاءة الخطوط وأجزاء الخطوط المرئية في المنطقة المركزية محل الاهتمام ( منطقة العرض ).
تم تطوير الخوارزمية في عام 1967 أثناء عمل داني كوهين وإيفان ساذرلاند على جهاز محاكاة الطيران . [ 1 ]
الخوارزمية
تتضمن الخوارزمية السطر أو تستبعده أو تتضمنه جزئياً بناءً على ما إذا كان:
- تقع كلتا النقطتين الطرفيتين في منطقة العرض (عملية OR الثنائية للنقطتين الطرفيتين = 0000): قبول بسيط .
- تشترك نقطتا النهاية في منطقة واحدة على الأقل غير مرئية، مما يعني أن الخط لا يعبر المنطقة المرئية. (عملية AND الثنائية لنقطتي النهاية ≠ 0000): رفض بديهي .
- تقع النقطتان الطرفيتان في منطقتين مختلفتين: في هذه الحالة غير البسيطة، يحدد البرنامج إحدى النقطتين خارج منطقة العرض (ستكون هناك نقطة واحدة على الأقل خارجها). ثم تُحسب نقطة التقاطع بين النقطة الخارجية وحدود منطقة العرض الممتدة (أي باستخدام المعادلة البارامترية للخط)، وتُستبدل النقطة الخارجية بهذه النقطة الجديدة. يتكرر البرنامج حتى يتم قبول أو رفض النقطة بشكل واضح.
تُسمى الأرقام في الشكل أدناه رموز الإخراج . يُحسب رمز إخراج لكل نقطة من النقطتين على الخط. يتكون رمز الإخراج من 4 بتات للقص ثنائي الأبعاد، أو 6 بتات في حالة القص ثلاثي الأبعاد. تُضبط البتة الأولى على 1 إذا كانت النقطة أعلى من نافذة العرض. تمثل البتات في رمز الإخراج ثنائي الأبعاد: أعلى، أسفل، يمين، يسار. على سبيل المثال، يُمثل رمز الإخراج 1010 نقطة تقع في أعلى يمين نافذة العرض.
غادر وسط المدينة يمين قمة 1001 1000 1010 وسط المدينة ٠٠٠١ 0000 0010 قاع 0101 0100 0110
لاحظ أنه يجب إعادة حساب رموز الإخراج لنقاط النهاية في كل تكرار بعد حدوث عملية القص.
لا يمكن استخدام خوارزمية كوهين-سوذرلاند إلا على نافذة قص مستطيلة .
مثال على تطبيق بلغة C++
typedef int OutCode ;const int INSIDE = 0b0000 ; const int LEFT = 0b0001 ; const int RIGHT = 0b0010 ; const int BOTTOM = 0b0100 ; const int TOP = 0b1000 ;// حساب رمز البت لنقطة (x, y) باستخدام مستطيل القطع // المحدد قطريًا بواسطة (xmin, ymin) و (xmax, ymax)// افترض أن xmax و xmin و ymax و ymin هي ثوابت عامة.OutCode ComputeOutCode ( double x , double y ) { OutCode code = INSIDE ; // تم تهيئتها لتكون داخل نافذة القصإذا كانت قيمة x أقل من xmin ، فسيتم تعيين الكود إلى يسار نافذة القص ، وإلا فسيتم تعيينه إلى LEFT . أما إذا كانت قيمة x أكبر من xmax ، فسيتم تعيين الكود إلى يمين نافذة القص ، وإلا فسيتم تعيينه إلى RIGHT . وإذا كانت قيمة y أقل من ymin ، فسيتم تعيين الكود إلى أسفل نافذة القص، وإلا فسيتم تعيينه إلى BOTTOM . أما إذا كانت قيمة y أكبر من ymax ، فسيتم تعيين الكود إلى أعلى نافذة القص ، وإلا فسيتم تعيينه إلى TOP .رمز الإرجاع ؛ }// تقوم خوارزمية قص كوهين-ساذرلاند بقص خط من // النقطة P0 = (x0, y0) إلى النقطة P1 = (x1, y1) مقابل مستطيل قطره من (xmin, ymin) إلى (xmax, ymax). bool CohenSutherlandLineClip ( double & x0 , double & y0 , double & x1 , double & y1 ) { // حساب رموز الإخراج للنقاط P0 وP1 وأي نقطة تقع خارج مستطيل القص OutCode outcode0 = ComputeOutCode ( x0 , y0 ); OutCode outcode1 = ComputeOutCode ( x1 , y1 ); bool accept = false ;بينما ( صحيح ) { إذا ( ! ( outcode0 | outcode1 )) { // عملية OR الثنائية تساوي 0: كلا النقطتين داخل النافذة؛ قبول واضح والخروج من الحلقة accept = صحيح ؛ break ؛ } وإلا إذا ( outcode0 & outcode1 ) { // عملية AND الثنائية لا تساوي 0: كلا النقطتين تشتركان في منطقة خارجية (يسار، يمين، أعلى، // أو أسفل)، لذا يجب أن تكونا كلتاهما خارج النافذة؛ الخروج من الحلقة (القبول خطأ) break ؛ } وإلا { // فشل كلا الاختبارين، لذا احسب قطعة الخط المراد قصها // من نقطة خارجية إلى تقاطع مع حافة القص double x ، y ؛// توجد نقطة نهاية واحدة على الأقل خارج مستطيل القص؛ اخترها. OutCode outcodeOut = outcode1 > outcode0 ? outcode1 : outcode0 ;// الآن، أوجد نقطة التقاطع؛ // استخدم الصيغ: // الميل = (y1 - y0) / (x1 - x0) // x = x0 + (1 / الميل) * (ym - y0)، حيث ym هي ymin أو ymax // y = y0 + الميل * (xm - x0)، حيث xm هي xmin أو xmax // لا داعي للقلق بشأن القسمة على صفر لأنه في كل حالة، // يضمن بت الإخراج الذي يتم اختباره أن المقام غير صفري إذا ( outcodeOut & TOP ) { // النقطة أعلى نافذة القص x = x0 + ( x1 - x0 ) * ( ymax - y0 ) / ( y1 - y0 ); y = ymax ; } else if ( outcodeOut & BOTTOM ) { // النقطة أسفل نافذة القص x = x0 + ( x1 - x0 ) * ( ymin - y0 ) / ( y1 - y0 ); y = ymin ; } else if ( outcodeOut & RIGHT ) { // النقطة على يمين نافذة القص y = y0 + ( y1 - y0 ) * ( xmax - x0 ) / ( x1 - x0 ); x = xmax ; } else if ( outcodeOut & LEFT ) { // النقطة على يسار نافذة القص y = y0 + ( y1 - y0 ) * ( xmin - x0 ) / ( x1 - x0 ); x = xmin ; }// الآن ننقل النقطة الخارجية إلى نقطة التقاطع للقص // ونستعد للمرحلة التالية. إذا كان ( outcodeOut == outcode0 ) { x0 = x ; y0 = y ; outcode0 = ComputeOutCode ( x0 , y0 ); } else { x1 = x ; y1 = y ; outcode1 = ComputeOutCode ( x1 , y1 ); } } } return accept ; }ملحوظات
انظر أيضاً
الخوارزميات المستخدمة لنفس الغرض:
مراجع
- جيمس د. فولي. رسومات الحاسوب: المبادئ والتطبيق . أديسون-ويسلي بروفيشنال، 1996. ص 113.
روابط خارجية
- مكتبة جافا سكريبت لقص الخطوط المتعددة باستخدام خوارزمية كوهين-ساذرلاند
- تطبيق جافا سكريبت متحرك
- تطبيق دلفي
- تطبيق Stata
- خوارزميات قص الخطوط
