Модераторы: Rickert, Alexeis, BorisVorontsov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Алгоритм Коэна-Сазерленда, В чем ошибка? 
:(
    Опции темы
Relrin
Дата 28.2.2012, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 20.2.2012

Репутация: нет
Всего: нет



Разобравшись с "морфингом" квадрата в пятиугольник, пришло время нарисовать так называемое "окно", состоящее из 3х прямоугольников, но при этом они вместе формируют "зеркально написанную букву С", в которой фигура, при движении должна показывать только в этом окне. Алгоритм использовал Коэна-Сазерленда(привет википедия!), с дальнейшими изменениями. Правда пока что-то не очень получается, т.к. на вид, код и правилен (в отладчике считается все правильно). Но получается, что при запуске приложения рисует только "окно", а двигающийся объект, проходящий через это окно - нет. Прощу помощи и наставления на верный путь.  smile 
П.С. Заранее извиняюсь за быдлокод smile 

Собственно сам код:
Код

const int width=800, height=800; //Задаем ширину и высоту окна
float coordsline[2];

//Отрисовка многоугольника
void DrawPolygon(float X[], float Y[], float F[], float S[], float T[])
{
    int k,l,ResAnalise;
    static float tmp1[2],tmp2[2];
    glBegin(GL_LINE_LOOP);        
      glColor3f(0.0f, 1.0f, 0.0f);
    //for(k=0;k<5;k++)
    //  glVertex2f(X[k],Y[k]);
        for(k=1;k<=5;k++)
        {
            if(k<=4)
            {
                tmp1[0]=X[k-1];
                tmp1[1]=Y[k-1];
                tmp2[0]=X[k];
                tmp2[1]=Y[k];
            }
            else
            {
                tmp1[0]=X[0];
                tmp1[1]=Y[0];
                tmp2[0]=X[4];
                tmp2[1]=Y[4];
            }
            for(l=0;l<=2;l++)
            {
                switch(l)
                {
                    case 0:
                        {
                            ResAnalise=KohenSutherland(F,tmp1,tmp2);
                            if(ResAnalise==0) glVertex2f(coordsline[0],coordsline[1]);
                            break;
                        }
                    case 1:
                        {
                            ResAnalise=KohenSutherland(S,tmp1,tmp2);
                            if(ResAnalise==0) glVertex2f(coordsline[0],coordsline[1]);
                            break;
                        }
                    case 2:
                        {
                            ResAnalise=KohenSutherland(T,tmp1,tmp2);
                            if(ResAnalise==0) glVertex2f(coordsline[0],coordsline[1]);
                            break;
                        }
                }
            }
        }
    glEnd();
}

//Отрисовка окна 
void DrawRectangles(float F[], float S[], float T[])
{
    glBegin(GL_LINE_LOOP);
        glColor3f(1.0f, 1.0f, 1.0f);
        glVertex2f(F[0],F[2]);
        glVertex2f(F[0],F[3]);
        glVertex2f(F[1],F[3]);
        glVertex2f(F[1],T[2]);
        glVertex2f(T[0],T[2]);
        glVertex2f(T[0],T[3]);
        glVertex2f(S[0],T[3]);
        glVertex2f(S[0],F[2]);
    glEnd();
}

//Определение положения точки
//1 ~ 0001
//2 ~ 0010
//4 ~ 0100
//8 ~ 1000
static int LineCode(float Square[], float x, float y)
{
    int code=0;
    if(x<Square[0]) code+=1; 
        else if(x>Square[1]) code+=2;
    if(y<Square[2]) code+=4; 
        else if(y>Square[3]) code+=8;
    return code;
}

//Алгоритм Коэна-Сазерленда
int KohenSutherland(float F[4], float crdA[2], float crdB[2])
{
    int code_a, code_b, code;
    //проверяем на каждой части фигуры(т.к. состоит из 3ех прямоугольников)
    //получаем коды положений точек прямой
    code_a=LineCode(F,crdA[0],crdA[1]);
    code_b=LineCode(F,crdB[0],crdB[1]);
    //пока одна из точек отрезка вне прямоугольника...
    while(code_a | code_b)
    {
        //если обе точки с одной стороны прямоугольника, то отрезок не пересекает прямоугольник
        if(code_a & code_b) return -1;
        //в противном случае выбираем точку c с ненулевым кодом
        if(code_a) 
        {
            code=code_a;
            coordsline[0]=crdA[1];
            coordsline[1]=crdA[1];
        } 
        else 
        {
            code=code_b;
            coordsline[0]=crdB[1];
            coordsline[1]=crdB[1];
        }
        //если crdline[] левее  F[], то передвигаем crdline[] на прямую x = F[0]
        if(code & 1) 
        {
            coordsline[1]+=(crdA[1]-crdB[1])*(F[0]-coordsline[0])/(crdA[0]-crdB[0]);
            coordsline[0]=F[0];
        } 
        //если crdline[] правее F[], то передвигаем crdline[] на прямую x = F[1]
        else if(code & 2) 
        { 
             coordsline[1]+=(crdA[1]-crdB[1])*(F[1]-coordsline[0])/(crdA[0]-crdB[0]);
             coordsline[0]=F[1];
        }
        //если crdline[] ниже F[], то передвигаем crdline[] на прямую y = F[2]
        
        else if (code & 4) 
        {
             coordsline[0]+=(crdA[0]-crdB[0])*(F[2]-coordsline[1])/(crdA[1]-crdB[1]);
             coordsline[1]=F[2];
        } 
        //если crdline[] выше F[], то передвигаем crdline[] на прямую y = F[3]
        else if (code & 8) 
        {
             coordsline[0]+=(crdA[0]-crdB[0])*(F[3]-coordsline[1])/(crdA[1]-crdB[1]);
             coordsline[1]=F[3];
        }
        //обновляем коды положений точек прямой
        if(code==code_a) code_a=LineCode(F,crdA[0],crdA[1]);
          else code_b=LineCode(F,crdB[0],crdB[1]);
    }
    return 0;
}

//Главная функция, отвечающая за отображение фигур, точек, и т.д.
void display() 
{
    static int i,j;
    //Шаг перемещения
    static float deltaX[5],deltaY[5];
    static float coords[4];
    //Начальные и конечные координаты перемещения фигуры
    float StartX[5]={-4.5, -4.5, -3.0, -3.0, -3.0};
    float StartY[5]={ 1.0,  2.5,  2.5,  2.5,  1.0};
    float EndX[5]={ 4.5,  4.9,  3.7,   2.5,  2.9};
    float EndY[5]={-2.3, -0.9, -0.2,  -0.9, -2.3};
    //Отсекающее окно, состоящее из 3х прямоугольников: {Xл,Xп,Yн,Yв}
    float FirstRectangle[4]={-2.0, 1.0,  1.5, 2.5};
    float SeconRectangle[4]={ 0.0, 1.0, -0.5, 2.5};
    float ThirdRectangle[4]={-2.0, 1.0, -1.5,-0.5};

    //Отрисовка окна
    glClear(GL_COLOR_BUFFER_BIT);
    DrawRectangles(FirstRectangle,SeconRectangle,ThirdRectangle);
    glFlush();

    //определяем дельты
    for(i=0;i<5;i++)
    {
        deltaX[i]=(EndX[i]-StartX[i])/30;
        deltaY[i]=(EndY[i]-StartY[i])/30;
    }
    
    //Полиморфинг фигуры: квадрат -> пятиугольник
    for(i=0;i<=30;i++)
    {
        glFinish();
        //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //закоментить-включить шлейф
        DrawPolygon(StartX,StartY,FirstRectangle,SeconRectangle,ThirdRectangle);
        for(j=0;j<5;j++)
        {
            StartX[j]=StartX[j]+deltaX[j];
            StartY[j]=StartY[j]+deltaY[j];
        }
        Sleep(50);
        glutPostRedisplay();
    }
}

//Запуск GLUT как консолльное приложение
int main(int argc, char** argv) 
{
    glutInit(&argc, argv);                         
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); 
    glutInitWindowSize(width,height);            
    glutInitWindowPosition(0,0);                
    glutCreateWindow("Test");  
    glOrtho(-5.0, 5.0, -5.0, 5.0, -1, 1);        
    glutDisplayFunc(display);                     
    glutMainLoop();                                
    return 0;
}


Это сообщение отредактировал(а) Relrin - 28.2.2012, 18:37
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Вы можете найти полезным что...
Alexeis
Rickert
  • Английская документация по DirectX лежит где-то здесь.
  • Английская документация по OpenGL лежит где-то там.
  • Гейм-дев у нас обсуждают где-то тут

Ждём вас! С уважением, Alexeis, Rickert.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Мультимедия, OpenGL/DirectX | Следующая тема »


 




[ Время генерации скрипта: 0.0469 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.