QuadTree рисует только в верхнем правом углу окна - PullRequest
0 голосов
/ 01 ноября 2018

Я написал эту программу для отображения некоторых точек, которые хранятся в четырехугольном дереве. По сути, я пытаюсь смоделировать галактику, следуя алгоритму Барнс-Хата. Прежде чем идти дальше, я не совсем уверен, правильно ли закодировано мое дерево квадов, и я хочу отобразить все точки в окне, используя OpenGL. Единственная область, которая рисуется на экране, находится в правом верхнем углу, и я не могу понять, почему это так.

Вот мой код. Пожалуйста, дайте мне знать, если необходимы разъяснения:

quadtree.h

#pragma once
#include <vector>
using namespace std;

class Point
{
public:
    Point(double x, double y);
    double x;
    double y;
};

class Rectangle
{
public:
    Rectangle(double x, double y, double width, double height);
    double x;
    double y;
    double width;
    double height;
    bool contains(Point* p);
};

class QuadTree
{
public:
    QuadTree();
    QuadTree(Rectangle* boundary, int capacity);
    Rectangle* boundary;
    int capacity;
    vector<Point*> points;
    QuadTree* NE;
    QuadTree* NW;
    QuadTree* SW;
    QuadTree* SE;
    bool divided;
    void subdivide();
    void buildTree();
    bool insertToNode(Point* p);

};

quadtree.cpp

#include "quadtree.h"
#include <random>
#include <GLFW/glfw3.h>
#include <iostream>
#include <chrono>
using namespace std;

Point::Point(double x, double y)
{
    this->x = x;
    this->y = y;
}

Rectangle::Rectangle(double x, double y, double width, double height)
{
    this->x = x;
    this->y = y;
    this->width = width;
    this->height = height;
}

bool Rectangle::contains(Point* p)
{
    return (p->x >= this->x - this->width &&
        p->x < this->x + this->width &&
        p->y >= this->y - this->height &&
        p->y < this->y + this->height);
}

QuadTree::QuadTree()
{
    this->boundary = new Rectangle(1, 1, 1, 1);
    this->capacity = 5000;
    this->divided = false;
    Rectangle* ne = new Rectangle(this->boundary->x + (this->boundary->width / 2), this->boundary->y - (this->boundary->height / 2), this->boundary->width / 2, this->boundary->height / 2);
    Rectangle* nw = new Rectangle(this->boundary->x - (this->boundary->width / 2), this->boundary->y - (this->boundary->height / 2), this->boundary->width / 2, this->boundary->height / 2);
    Rectangle* sw = new Rectangle(this->boundary->x - (this->boundary->width / 2), this->boundary->y + (this->boundary->height / 2), this->boundary->width / 2, this->boundary->height / 2);
    Rectangle* se = new Rectangle(this->boundary->x + (this->boundary->width / 2), this->boundary->y + (this->boundary->height / 2), this->boundary->width / 2, this->boundary->height / 2);
this->NE = new QuadTree(ne, this->capacity);
this->NW = new QuadTree(nw, this->capacity);
this->SW = new QuadTree(sw, this->capacity);
this->SE = new QuadTree(se, this->capacity);
this->divided = true;
}

QuadTree::QuadTree(Rectangle* boundary, int capacity)
{
    this->boundary = boundary;
    this->capacity = 5000;
    this->divided = false;
}

void QuadTree::subdivide()
{
    Rectangle* ne = new Rectangle(this->boundary->x + (this->boundary->width / 2), this->boundary->y - (this->boundary->height / 2), this->boundary->width / 2, this->boundary->height / 2);
    Rectangle* nw = new Rectangle(this->boundary->x - (this->boundary->width / 2), this->boundary->y - (this->boundary->height / 2), this->boundary->width / 2, this->boundary->height / 2);
    Rectangle* sw = new Rectangle(this->boundary->x - (this->boundary->width / 2), this->boundary->y + (this->boundary->height / 2), this->boundary->width / 2, this->boundary->height / 2);
    Rectangle* se = new Rectangle(this->boundary->x + (this->boundary->width / 2), this->boundary->y + (this->boundary->height / 2), this->boundary->width / 2, this->boundary->height / 2);
    this->NE = new QuadTree(ne, this->capacity);
    this->NW = new QuadTree(nw, this->capacity);
    this->SW = new QuadTree(sw, this->capacity);
    this->SE = new QuadTree(se, this->capacity);
    this->divided = true;
}

void QuadTree::buildTree()
{
    std::default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count());
    std::uniform_real_distribution<double> distribution(-1.0, 1.0);
    double x;
    double y;

    for (int i = 0; i < 5000; i++)
    {
        x = distribution(generator);
        y = distribution(generator);
        this->insertToNode(new Point(x, y));
    }
}

bool QuadTree::insertToNode(Point* p)
{
    if (!this->boundary->contains(p))
    {
        return false;
    }

    if (this->points.size() < this->capacity)
    {
        this->points.push_back(p);
        return true;
    }

    else
    {
        if (!this->divided)
        {
            this->subdivide();
        }

        if (this->NE->insertToNode(p))
        {
            return true;
        }
        else if (this->NW->insertToNode(p))
        {
            return true;
        }
        else if (this->SW->insertToNode(p))
        {
            return true;
        }
        else if (this->SE->insertToNode(p))
        {
            return true;
        }
    }
}

main.cpp

#include <iostream>
#include "quadtree.h"
#include <GLFW/glfw3.h>
using namespace std;

QuadTree* aTree = new QuadTree();

void display() 
{
    glColor3f(1.0, 1.0, 1.0);
    glBegin(GL_POINTS);

    for (int i = 0; i < aTree->points.size(); i++)
    {
        glColor3f(0.8, 0.196078, 0.6);
        glVertex2d(aTree->points[i]->x, aTree->points[i]->y);
    }

    glEnd();
    glFlush();
}

int main()
{
    aTree->buildTree();
    GLFWwindow* window;

    if (!glfwInit()) {
        cout << "Error initializing GLFW" << std::endl;
        return -1;

    }
    window = glfwCreateWindow(800, 800, "Barne's Hut", NULL, NULL);
    if (!window)
    {
        cout << "Error creating window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    while (!glfwWindowShouldClose(window))
    {       
        display();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwTerminate();

    system("pause");
    return 0;
}

1 Ответ

0 голосов
/ 01 ноября 2018

Если вы не установите матрицу проекции, то объем просмотра, который проецируется на порт просмотра, является нормализованным пространством устройства. Это куб с левым нижним рядом (-1, -1, -1) и правым верхним дальним от (1, 1, 1).

Используйте glOrtho, чтобы определить объем в кубическом виде (ортографическая проекция) ваших потребностей.

Установите диапазон от допустимого до правого [0, 1] и диапазон от нижнего до верхнего тоже.
Добавьте следующую ложь кода прямо перед циклом рендеринга:

glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0.0, 1.0, 0.0, 1.0, -1.0, 1.0 );

while (!glfwWindowShouldClose(window))
{
    ....
}
...