Интернет магазин китайских планшетных компьютеров



Компьютеры - Алгоритм Коэна Сазерленда - Пример реализации

23 января 2011


Оглавление:
1. Алгоритм Коэна Сазерленда
2. Пример реализации



Пример реализации на языке C для двумерной модели:

#define LEFT  1  /* двоичное 0001 */
#define RIGHT 2  /* двоичное 0010 */
#define BOT   4  /* двоичное 0100 */
#define TOP   8  /* двоичное 1000 */
 
/* точка */
struct point {
        double x, y;
};
 
/* прямоугольник */
struct rect {
        double x_min, y_min, x_max, y_max;
};
 
/* вычисление кода точки
   r : указатель на struct rect; p : указатель на struct point */
#define vcode \
       ->x <->x_min) ? LEFT : 0)  +  /* +1 если точка левее прямоугольника */ \
        ->x >->x_max) ? RIGHT : 0) +  /* +2 если точка правее прямоугольника */\
        ->y <->y_min) ? BOT : 0)   +  /* +4 если точка ниже прямоугольника */  \
        ->y >->y_max) ? TOP : 0))     /* +8 если точка выше прямоугольника */
 
/* если отрезок ab не пересекает прямоугольник r, функция возвращает -1;
   если отрезок ab пересекает прямоугольник r, функция возвращает 0 и отсекает
   те части отрезка, которые находятся вне прямоугольника */
int cohen_sutherland 
{
        int code_a, code_b, code; /* код конечных точек отрезка */
        struct point *c; /* одна из точек */
 
        code_a = vcode;
        code_b = vcode;
 
        /* пока одна из точек отрезка вне прямоугольника */
        while  {
                /* если обе точки с одной стороны прямоугольника, то отрезок не пересекает прямоугольник */
                if 
                        return -1;
 
                /* выбираем точку c с ненулевым кодом */
                if  {
                        code = code_a;
                        c = a;
                } else {
                        code = code_b;
                        c = b;
                }
 
                /* если c левее r, то передвигаем c на прямую x = r->x_min
                   если c правее r, то передвигаем c на прямую x = r->x_max */
                if  {
                        c->y +=  *  / ;
                        c->x = r->x_min;
                } else if  {
                        c->y +=  *  / ;
                        c->x = r->x_max;
                }
                /* если c ниже r, то передвигаем c на прямую y = r->y_min
                   если c выше r, то передвигаем c на прямую y = r->y_max */
                if  {
                        c->x +=  *  / ;
                        c->y = r->y_min;
                } else if  {
                        c->x +=  *  / ;
                        c->y = r->y_max;
                }
 
                /* обновляем код */
                if 
                        code_a = vcode;
                else
                        code_b = vcode;
        }
 
        /* оба кода равны 0, следовательно обе точки в прямоугольнике */
        return 0;
}

Пример реализации на языке C для трёхмерной модели:

#define BOTTOM 1   // 00 000001
#define LEFT   2   // 00 000010
#define TOP    4   // 00 000100
#define RIGHT  8   // 00 001000
#define BACK  16   // 00 010000
#define FRONT 32   // 00 100000
 
typedef struct Area {
        float xlt,ylt,zlt; // Координаты левого верхнего угла ближней грани
        float xrb,yrb,zrb; // Координаты правого нижнего угла дальней грани
} Area;
 
int GetCode  {
        int code = 0;
        if      // Точка выше области отсечения
                code |= TOP;
        else if // Точка ниже области отсечения
                code |= BOTTOM;
        if      // Точка правее области отсечения
                code |= RIGHT;
        else if // Точка левее области отсечения
                code |= LEFT;
        if      // Точка перед областью отсечения
                code |= FRONT;
        else if // Точка заобластью отсечения      
                code |= BACK;
        return code;
}
 
// Трёхмерное отсечение методом Коэна-Сазерленда.
// beg - координаты начала отрезка
// end - координаты конца отрезка 
// anArea - координаты отсекающей области
void CS_Clip
{
        // Коды концов отрезка
        int outcode0 = 0, outcode1 = 0, outcodeOut = 0;
 
        char codes = {"000000","000000"};
        float temp;
 
        // Флаг видимости и флаг завершения отсечения
        bool accept = false, done = false;
 
        outcode0 = GetCode; // Вычисляем начальные коды концов отрезка
        outcode1 = GetCode;
        do
        {
                float x, y, z;
                if ) { // Отрезок полностью видимый
                        accept = true;
                        done = true;
                }
                else if  // Отрезок полностью невидимый
                        done = true;
                else {                          // Отрезок частично видимый. Вычисление точек пересечения отрезка и области отсечения
                        outcodeOut = outcode0 ? outcode0: outcode1;
                        if {
                                x = beg+*/;
                                z = beg+*/;
                                y = anArea.ylt;
                        }
                        else if {
                                x = beg+*/;
                                z = beg+*/;
                                y = anArea.yrb;
                        }
                        else if {
                                y = beg+*/;
                                z = beg+*/;
                                x = anArea.xrb;
                        }
                        else if {
                                y = beg+*/;
                                z = beg+*/;
                                x = anArea.xlt;
                        }
                        else if {
                                x = beg+*/;
                                y = beg+*/;
                                z = anArea.zrb;
                        }
                        else if {
                                x = beg+*/;
                                y = beg+*/;
                                z = anArea.zlt;
                        }
                        if  {
                                temp = x;
                                temp = y;
                                temp = z;
                                outcode0 = GetCode;
                        }
                        else {
                                temp = x;
                                temp = y;
                                temp = z;
                                outcode1 = GetCode;
                        }
                }
        }while ;    
        if { // Отрезок полностью видимый. Вывод отрезка на экран.
                LINE;
        }
}


Просмотров: 3679


<<< Алгоритм Киркпатрика
Алгоритм Уайлера Атертона >>>