OpenGl: Некорректное отображение квадратов

182
19 декабря 2016, 19:46

Здравствуйте. Есть программа, которая ищет ромбы в множестве заданных точек и выводит на экран координаты и площадь самого большого из них. Было дано задание вывести все найденные ромбы на экран с помощью OpenGL и выделить больший из них. Проблема в том, что программа, от случая к случаю, рисует вместо ромбов огрызки от них. То есть, забывает дорисовать четверть ромба. В чем может быть проблема?

#include <iostream>
#include <vector>
#include <cmath>
#include <clocale>
#include "glut.h"
using namespace std;
int U[4];
int V[4];
int sum=0;//счётчик количества ромбов
vector< vector<int> > rs(100*100);//ромбы
struct point{int x; int y;};
/* начальная ширина и высота окна */
GLint Width = 1024, Height = 1024;
/* эта функция управляет всем выводом на экран */
void Display(void)
{
glClearColor(255, 255, 255, 1);
glClear(GL_COLOR_BUFFER_BIT);
// Абцисса, ордината с переносом в центр окна (иначе не хватает трех координатных углов, а орты не видны)
glColor3ub(0,0,0);
glBegin(GL_LINES);
        glVertex2i(0,512);
        glVertex2i(1024,512);
        glVertex2i(512,1024);
        glVertex2i(512,0);
glEnd();
// цикл вывода остальных найденных ромбов
glColor3ub(0,0,0);
glBegin(GL_QUADS);
for (int i=0; i<sum; i++)
{
    glVertex2i(rs[i][0]*20+512,rs[i][1]*20+512);
    glVertex2i(rs[i][2]*20+512,rs[i][3]*20+512);
    glVertex2i(rs[i][4]*20+512,rs[i][5]*20+512);
    glVertex2i(rs[i][6]*20+512,rs[i][7]*20+512);
}
glEnd();
    //вывод самого наваристого ромба
glColor3ub(255,0,0);
glBegin(GL_QUADS);
for (int i=0; i<4; i++)
        glVertex2i(U[i]*20+512,V[i]*20+512);
glEnd();
glColor3ub(255,255,255);
glBegin(GL_QUADS);
        glVertex2i(-10*20+512,-20*20+512);
        glVertex2i(-10*20+512,-20*20+512);
        glVertex2i(-30*20+512,-20*20+512);
        glVertex2i(-30*20+512,-20*20+512);
glEnd();
glFinish();
}
/* Функция вызывается при изменении размеров окна */
void Reshape(GLint w, GLint h)
{
    Width = w;
    Height = h;
    /* устанавливаем размеры области отображения */
    glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, w, 0, h, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/* Функция обрабатывает сообщения от клавиатуры */
void Keyboard(unsigned char key, int x, int y)
{
#define ESCAPE '\033'
if( key == ESCAPE )
    exit(0);
}
const double e=0.001; // точность при сравнении вещественных чисел
void msort(double a[])// пузырьковая сортировка по возрастанию
{
double temp;
for(int i=0;i<=4;i++)
{
    for(int j=i+1;j<=5;j++)
    {
        if(a[i]>a[j])
        {
            temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
    }
}
}
    double length(double x1,double y1,double x2,double y2)//длина отрезка через             координаты концов
{
    return sqrt((pow((x2-x1),2.0)+pow((y2-y1),2.0)));
}
double tangens(double x1,double y1,double x2,double y2)//угол наклона k прямой вида     y=kx+b, через координаты точек
{
if(x1==x2)
    return 99999.0;//вертикальная прямая с наклоном ~бесконечность
else
return (y2-y1)/(x2-x1);
}
bool parallel(double a[])//true если есть лишь 2 пары парралельных сторон
{
int temp=0;
for(int i=0;i<=4;i++)
{
    for(int j=i+1;j<=5;j++)
    {
        if(a[i]==a[j])
        {   
            temp++;
        }
    }
}
if(temp==2)
    return true;
return false;
}
void main(int argc, char *argv[])
{
setlocale (LC_ALL, "Russian");
int n,first=0,second=0,third=0,fourth=0;
bool isrhombus=false;
double slope[6],d[6],square=0.0,maxsquare=0.0;
cout << "Введите количество точек:";//количество точек
cin >> n;
if(n<4)
{
    cout << "Недостаточное количество точек.\n";
    return;
}
vector < vector <int> > point(n,vector <int> (2)); //заводим массив размера [n][2] для X и Y каждой точки
cout << "\n" << "Введите координаты (x:y) для этих точек:" << "\n";
for(int i=0;i<n;i++)
{
    cout << i+1 << " точка: ";
    cin >> point[i][0] >> point[i][1];//координаты
}
//закончили ввод точек
for(int i=0;i<=n-4;i++)
{
    for(int j=i+1;j<=n-3;j++)
    {
        for(int k=j+1;k<=n-2;k++)
        {
            for(int l=k+1;l<=n-1;l++)//4 циклами берём каждую четвёрку точек, и вычисляем все длины и наклоны
            {
                d[0]=length(point[i][0],point[i][1],point[j][0],point[j][1]);//длины
                d[1]=length(point[i][0],point[i][1],point[k][0],point[k][1]);
                d[2]=length(point[i][0],point[i][1],point[l][0],point[l][1]);
                d[3]=length(point[j][0],point[j][1],point[k][0],point[k][1]);
                d[4]=length(point[j][0],point[j][1],point[l][0],point[l][1]);
                d[5]=length(point[k][0],point[k][1],point[l][0],point[l][1]);
                slope[0]=tangens(point[i][0],point[i][1],point[j][0],point[j][1]);//наклоны 
                slope[1]=tangens(point[i][0],point[i][1],point[k][0],point[k][1]);
                slope[2]=tangens(point[i][0],point[i][1],point[l][0],point[l][1]);
                slope[3]=tangens(point[j][0],point[j][1],point[k][0],point[k][1]);
                slope[4]=tangens(point[j][0],point[j][1],point[l][0],point[l][1]);
                slope[5]=tangens(point[k][0],point[k][1],point[l][0],point[l][1]);
                msort(d); // сортируем длины по возрастанию
                if ((((abs(d[0]-d[1])<e)&&(abs(d[0]-d[2])<e)&&(d[0]-d[3]<e))||((abs(d[1]-d[2])<e)&&(abs(d[1]-d[3])<e)&&(abs(d[1]-d[4])<e)))&&(parallel(slope)))
                {//длинный if - это проверка являются ли текущие точки описание ромба: стороны равны и есть параллельные (учитывается что одна из диагоналей может быть меньше стороны)
                    isrhombus=true;//подтверждаем что ромб есть
                    if(abs(d[0]-d[1])<e)//если меньшая диагональ больше стороны
                    {
                        square=d[5]*d[4]/2;
                    }
                    else//если меньшая диагональ меньше стороны
                    {
                        square=d[0]*d[5]/2;
                    }
                    if(square)
                    {
                        rs[sum].push_back(point[i][0]);
                        rs[sum].push_back(point[i][1]);
                        rs[sum].push_back(point[j][0]);
                        rs[sum].push_back(point[j][1]);
                        rs[sum].push_back(point[k][0]);
                        rs[sum].push_back(point[k][1]);
                        rs[sum].push_back(point[l][0]);
                        rs[sum].push_back(point[l][1]);
                        sum++;
                    }
                    if(square>maxsquare)
                    {
                        maxsquare=square;
                        first=i;//запоминаем координаты ромба, если его площадь больше предыдущего max
                        second=j;
                        third=k;
                        fourth=l;
                    }
                }
            }
        }
    }
}
if(isrhombus)
{
    cout << "Number of rhombuses: " << sum << "\n";
    for(int i=0;i<sum;i++)
        cout << i+1 << ": (" << rs[i][0] << ", " << rs[i][1] << ") (" << rs[i][2] << ", " << rs[i][3] << ") (" << rs[i][4] << ", " << rs[i][5] << ") (" << rs[i][6] << ", " << rs[i][7] << ")\n";
    cout << "Максимальная площадь: " << maxsquare << "\n";
    cout << first+1 << " point - x=" << point[first][0] << ", y=" << point[first][1] << "\n";
    cout << second+1 << " point - x=" << point[second][0] << ", y=" << point[second][1] << "\n";
    cout << third+1 << " point - x=" << point[third][0] << ", y=" << point[third][1] << "\n";
    cout << fourth+1 << " point - x=" << point[fourth][0] << ", y=" << point[fourth][1] << "\n";
U[0]=point[first][0]; V[0]=point[first][1];
U[1]=point[second][0]; V[1]=point[second][1];
U[2]=point[third][0]; V[2]=point[third][1];
U[3]=point[fourth][0];  V[3]=point[fourth][1];
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(500, 500);
glutCreateWindow("Example");
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Keyboard);
glutMainLoop();
}
else
{
cout << "Ромбов не найдено.\n";
}
return;

}

Answer 1

Вопрос решен. Для корректного отображения нужен последовательный ввод точек (по или против часовой стрелке). Гораздо проще вопрос решается заменой функции вывода GL_QUADS на GL_TRIANGLE_FAN.

READ ALSO
Работа с файлами и структурами. Удалить запись по ее номеру.

Работа с файлами и структурами. Удалить запись по ее номеру.

Здравствуйте, не знаю как удалить элемент по заданному номеруМы создаем бинарный файл, в консоль заполняем структуру и она записывается...

293
Вопрос по циклам

Вопрос по циклам

Привет, ребят! У меня вопросПочему в коде ниже place_number в конце равен коду последнего символа?

228
Что такое pair и где использовать?

Что такое pair и где использовать?

Не могу понять зачем такое объединение двух объектов разного или одного типа, в один объект? И чем это отличается от map? И как или какой смысл...

220
Полиморфизм

Полиморфизм

Требуются помощь с реализацией трех задачДумаю над их реализацией больше недели

186