Merge branch 'main' of http://git.hexaquo.at/mgs/quickhull into main
This commit is contained in:
commit
3cfa15a33c
274
Display.cpp
274
Display.cpp
@ -1,16 +1,71 @@
|
|||||||
|
|
||||||
// make sure sfml is installed:
|
|
||||||
// linux - sudo apt-get install libsfml-dev
|
|
||||||
// windows - manual dl from https://www.sfml-dev.org/download.php
|
|
||||||
#include <SFML/Graphics.hpp>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Point.h"
|
#include "Point.h"
|
||||||
|
#include "Utility.h"
|
||||||
|
|
||||||
|
Display::Display (const std::vector<Point> &pts)
|
||||||
|
{
|
||||||
|
if (!m_font.loadFromFile("arial.ttf"))
|
||||||
|
{
|
||||||
|
std::cerr << "font arial.ttf could not be loaded!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_textStatus.setPosition(OFFSET, HEIGHT - 2*OFFSET);
|
||||||
|
m_textStatus.setFont(m_font);
|
||||||
|
m_textStatus.setString("initializing...");
|
||||||
|
m_textStatus.setCharacterSize(12);
|
||||||
|
m_textStatus.setFillColor(sf::Color::Black);
|
||||||
|
|
||||||
|
size_t points = pts.size();
|
||||||
|
for (size_t i = 0; i < points; ++i)
|
||||||
|
{
|
||||||
|
const Point& pt = pts[i];
|
||||||
|
sf::CircleShape shape(OFFSET);
|
||||||
|
//shape.setPosition(pt.x() - OFFSET, pt.y() - OFFSET); // handle with origin or manually calc position
|
||||||
|
shape.setOrigin(OFFSET, OFFSET);
|
||||||
|
shape.setPosition(pt.x(), pt.y());
|
||||||
|
shape.setFillColor(sf::Color::Green);
|
||||||
|
shape.setOutlineThickness(1.f);
|
||||||
|
shape.setOutlineColor(sf::Color::Black);
|
||||||
|
m_points.push_back(shape);
|
||||||
|
//m_points.append(shape);
|
||||||
|
|
||||||
|
sf::Text label;
|
||||||
|
//label.setPosition(pt.x() - OFFSET / 2, pt.y() - OFFSET / 2 - 3);
|
||||||
|
label.setOrigin(OFFSET / 2 - 1, OFFSET / 2 + 3);
|
||||||
|
label.setPosition(pt.x(), pt.y());
|
||||||
|
label.setFont(m_font);
|
||||||
|
label.setString(std::to_string(i));
|
||||||
|
label.setCharacterSize(12);
|
||||||
|
label.setFillColor(sf::Color::Black);
|
||||||
|
m_labels.push_back(label);
|
||||||
|
//m_points.append(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// multiple options possible:
|
||||||
|
// a) draw every frame, using elapsed time for updates
|
||||||
|
// --> not really needed because we have no animations... also uses a lot of performance
|
||||||
|
// b) checking every frame if elapsed time since last tick is larger than a specified offset, then draw the field
|
||||||
|
// --> mostly doing nothing but still uses a lot of performance O_o
|
||||||
|
// c) just start a simple (c++11 <3) non-busy sleep
|
||||||
|
// --> may delay user input / events but don't care atm :p
|
||||||
void Display::show()
|
void Display::show()
|
||||||
{
|
{
|
||||||
sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "SFML works!");
|
sf::ContextSettings settings;
|
||||||
|
settings.antialiasingLevel = 8;
|
||||||
|
|
||||||
|
sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "ALGO Prog2: Quickhull - visualization", sf::Style::Default, settings);
|
||||||
|
/* b)
|
||||||
|
window.setFramerateLimit(0.2);
|
||||||
|
|
||||||
|
sf::Clock clock;
|
||||||
|
sf::Time frameTime = sf::seconds(2); //sf::seconds(1.f / 60.f)
|
||||||
|
sf::Time timeSinceLastUpdate = frameTime; //sf::Time::Zero;*/
|
||||||
while (window.isOpen())
|
while (window.isOpen())
|
||||||
{
|
{
|
||||||
sf::Event event;
|
sf::Event event;
|
||||||
@ -20,19 +75,208 @@ void Display::show()
|
|||||||
window.close();
|
window.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
window.clear();
|
// a)
|
||||||
for (auto &pt : m_points)
|
//update(elapsed);
|
||||||
|
//render(window);
|
||||||
|
|
||||||
|
/* b)
|
||||||
|
timeSinceLastUpdate += clock.restart();
|
||||||
|
// only handle every few seconds because we need no animations
|
||||||
|
if (timeSinceLastUpdate >= frameTime)
|
||||||
{
|
{
|
||||||
sf::CircleShape shape(10.f);
|
std::cout << "entering update and render" << std::endl;
|
||||||
shape.setPosition(pt.x(), pt.y());
|
|
||||||
shape.setFillColor(sf::Color::Green);
|
// start by getting the most left and right point
|
||||||
window.draw(shape);
|
timeSinceLastUpdate -= frameTime;
|
||||||
}
|
|
||||||
window.display();
|
update();
|
||||||
|
render(window);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// c)
|
||||||
|
// choose a simple sleep
|
||||||
|
update();
|
||||||
|
render(window);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::setData(std::vector<Point> pts)
|
void Display::update ()
|
||||||
{
|
{
|
||||||
m_points = pts;
|
// TODO: maybe include Akl–Toussaint heuristic first?
|
||||||
|
// https://en.wikipedia.org/wiki/Convex_hull_algorithms#Akl%E2%80%93Toussaint_heuristic
|
||||||
|
|
||||||
|
unsigned int curStep = (m_step > 5) ? ((m_step - 2) % 4 + 2) : (m_step % 6); // skip init and first step after first run
|
||||||
|
|
||||||
|
std::string text = "(" + std::to_string(m_step) + ") step " + std::to_string(curStep) + ": ";
|
||||||
|
if (curStep == 1)
|
||||||
|
{
|
||||||
|
// first step: select min - max x coordinates
|
||||||
|
m_textStatus.setString(text + "select min - max x coordinates...");
|
||||||
|
|
||||||
|
/* EDIT: manual iteration for combining x and x minmax; also need not previous sorting
|
||||||
|
std::pair<Point, Point> minmax = getMinMaxX(m_points);
|
||||||
|
std::cout << "min: " << minmax.first.x() << ", " << minmax.first.y() <<
|
||||||
|
", max: " << minmax.second.x() << ", " << minmax.second.y() << std::endl;
|
||||||
|
|
||||||
|
m_hull.setPrimitiveType(sf::Lines);
|
||||||
|
m_hull.append(sf::Vertex(sf::Vector2f(minmax.first.x(), minmax.first.y()), sf::Color::Blue));
|
||||||
|
m_hull.append(sf::Vertex(sf::Vector2f(minmax.second.x(), minmax.second.y()), sf::Color::Blue));*/
|
||||||
|
|
||||||
|
// if use Akl–Toussaint heuristic
|
||||||
|
bool useAkl = false;
|
||||||
|
if (useAkl)
|
||||||
|
{
|
||||||
|
sf::Vector2f topLeft(WIDTH, HEIGHT);
|
||||||
|
sf::Vector2f topRight(0, HEIGHT);
|
||||||
|
sf::Vector2f botLeft(WIDTH, 0);
|
||||||
|
sf::Vector2f botRight(0, 0);
|
||||||
|
|
||||||
|
for (auto& pt : m_points)
|
||||||
|
{
|
||||||
|
sf::Vector2f pos = pt.getPosition();
|
||||||
|
float x = pos.x;
|
||||||
|
float y = pos.y;
|
||||||
|
// TODO: only check explicit x and y seperate!
|
||||||
|
if (x < topLeft.x && y < topLeft.y) topLeft = pos;
|
||||||
|
if (x > topRight.x && y < topLeft.y) topRight = pos;
|
||||||
|
if (x < botLeft.x && y > botLeft.y) botLeft = pos;
|
||||||
|
if (x > botRight.x && y > botRight.y) botRight = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: use a convex shape? Or build from vertices in render?
|
||||||
|
sf::ConvexShape convex;
|
||||||
|
convex.setPointCount(5);
|
||||||
|
convex.setPoint(0, topLeft);
|
||||||
|
convex.setPoint(0, topRight);
|
||||||
|
convex.setPoint(0, botRight);
|
||||||
|
convex.setPoint(0, botLeft);*/
|
||||||
|
|
||||||
|
//m_hull.setPrimitiveType(sf::Lines);
|
||||||
|
m_hull.setPrimitiveType(sf::LineStrip);
|
||||||
|
m_hull.append(sf::Vertex(topLeft, sf::Color::Blue));
|
||||||
|
m_hull.append(sf::Vertex(topRight, sf::Color::Blue));
|
||||||
|
m_hull.append(sf::Vertex(botRight, sf::Color::Blue));
|
||||||
|
m_hull.append(sf::Vertex(botLeft, sf::Color::Blue));
|
||||||
|
m_hull.append(sf::Vertex(topLeft, sf::Color::Blue));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sf::Vector2f left(WIDTH, HEIGHT);
|
||||||
|
sf::Vector2f right(0, 0);
|
||||||
|
|
||||||
|
for (auto& pt : m_points)
|
||||||
|
{
|
||||||
|
sf::Vector2f pos = pt.getPosition();
|
||||||
|
float x = pos.x;
|
||||||
|
float y = pos.y;
|
||||||
|
if (x < left.x) left = pos;
|
||||||
|
if (x > right.x) right = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
//m_hull.setPrimitiveType(sf::Lines);
|
||||||
|
m_hull.setPrimitiveType(sf::LineStrip);
|
||||||
|
m_hull.append(sf::Vertex(left, sf::Color::Blue));
|
||||||
|
m_hull.append(sf::Vertex(right, sf::Color::Blue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (curStep == 2)
|
||||||
|
{
|
||||||
|
// second step: split board and find furthest point
|
||||||
|
m_textStatus.setString(text + "split board and find furthest point...");
|
||||||
|
|
||||||
|
for (auto& pt : m_points)
|
||||||
|
{
|
||||||
|
pt.setFillColor(sign(
|
||||||
|
pt.getPosition().x, pt.getPosition().y,
|
||||||
|
m_hull[0].position.x, m_hull[0].position.y,
|
||||||
|
m_hull[1].position.x, m_hull[1].position.y) > 0 ? sf::Color::Red : sf::Color::Green);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (curStep == 3)
|
||||||
|
{
|
||||||
|
// third step: draw triangle, remove inner points
|
||||||
|
m_textStatus.setString(text + "find furthest point and draw triangle...");
|
||||||
|
|
||||||
|
sf::Vector2f pos = m_points[0].getPosition();
|
||||||
|
float maxDistance = 0;
|
||||||
|
for (auto& pt : m_points)
|
||||||
|
{
|
||||||
|
float distance = pDistance(
|
||||||
|
pt.getPosition().x, pt.getPosition().y,
|
||||||
|
m_hull[0].position.x, m_hull[0].position.y,
|
||||||
|
m_hull[1].position.x, m_hull[1].position.y);
|
||||||
|
|
||||||
|
if (pt.getFillColor() == sf::Color::Green)
|
||||||
|
{
|
||||||
|
std::cout << "distance to green point " << pt.getPosition().x << ", " << pt.getPosition().y << ": " << distance << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (pt.getFillColor() == sf::Color::Red)
|
||||||
|
{
|
||||||
|
std::cout << "distance to red point " << pt.getPosition().x << ", " << pt.getPosition().y << ": " << distance << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (distance > maxDistance)
|
||||||
|
{
|
||||||
|
pos = pt.getPosition();
|
||||||
|
maxDistance = distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxDistance > 0)
|
||||||
|
{
|
||||||
|
// TODO: not append but insert between last line points
|
||||||
|
m_hull.append(sf::Vertex(pos, sf::Color::Blue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (curStep == 4)
|
||||||
|
{
|
||||||
|
// fourth step: remove inner points
|
||||||
|
m_textStatus.setString(text + "remove inner points...");
|
||||||
|
}
|
||||||
|
else if (curStep == 5)
|
||||||
|
{
|
||||||
|
// fifth step: adding new hull point
|
||||||
|
|
||||||
|
// TEMP: TEST check if ends
|
||||||
|
//if (m_step >= 10) m_points.clear();
|
||||||
|
|
||||||
|
if (m_points.size() == 0) m_textStatus.setString(text + "finished calculating convex hull");
|
||||||
|
else m_textStatus.setString(text + "adding new hull point...");
|
||||||
|
}
|
||||||
|
else m_textStatus.setString(text + "invalid status!");
|
||||||
|
|
||||||
|
if (curStep != 5 || m_points.size() > 0) m_step++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::render (sf::RenderWindow &window)
|
||||||
|
{
|
||||||
|
window.clear(sf::Color::White);
|
||||||
|
|
||||||
|
// always print remaining points
|
||||||
|
/*size_t points = m_points.size();
|
||||||
|
for (size_t i = 0; i < points; ++i)
|
||||||
|
{
|
||||||
|
drawPoint(window, i);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//for (auto& pt : m_points) // points and labels should have the same size -> combine in one loop
|
||||||
|
size_t points = m_points.size();
|
||||||
|
for (size_t i = 0; i < points; ++i)
|
||||||
|
{
|
||||||
|
window.draw(m_points[i]);
|
||||||
|
window.draw(m_labels[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw already calculated hull
|
||||||
|
//if (step >= 1)
|
||||||
|
{
|
||||||
|
//window.draw(&m_hull[0], m_hull.size(), sf::Lines);
|
||||||
|
window.draw(&m_hull[0], m_hull.getVertexCount(), m_hull.getPrimitiveType());
|
||||||
|
}
|
||||||
|
|
||||||
|
window.draw(m_textStatus);
|
||||||
|
|
||||||
|
window.display();
|
||||||
}
|
}
|
28
Display.h
28
Display.h
@ -1,17 +1,39 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#ifndef DISPLAY_H
|
||||||
|
|
||||||
|
// make sure sfml is installed:
|
||||||
|
// linux - sudo apt-get install libsfml-dev
|
||||||
|
// windows - manual dl from https://www.sfml-dev.org/download.php
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
class Point;
|
class Point;
|
||||||
|
|
||||||
|
#define OFFSET 10.f
|
||||||
#define WIDTH 800
|
#define WIDTH 800
|
||||||
#define HEIGHT 600
|
#define HEIGHT 600
|
||||||
|
|
||||||
class Display
|
class Display
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::vector<Point> m_points;
|
sf::Font m_font;
|
||||||
|
sf::Text m_textStatus;
|
||||||
|
|
||||||
|
//std::vector<Point> m_points;
|
||||||
|
std::vector<sf::CircleShape> m_points;
|
||||||
|
std::vector<sf::Text> m_labels;
|
||||||
|
//sf::VertexArray m_points;
|
||||||
|
//sf::VertexArray m_labels;
|
||||||
|
|
||||||
|
//std::vector<sf::Vertex> m_hull;
|
||||||
|
sf::VertexArray m_hull;
|
||||||
|
|
||||||
|
unsigned int m_step = 0;
|
||||||
|
void update();
|
||||||
|
void render(sf::RenderWindow &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void show();
|
Display(const std::vector<Point> &);
|
||||||
|
|
||||||
void setData (std::vector<Point>);
|
void show();
|
||||||
};
|
};
|
||||||
|
#endif // DISPLAY_H
|
@ -1,2 +1,10 @@
|
|||||||
# quickhull
|
# quickhull
|
||||||
|
|
||||||
|
## TODO:
|
||||||
|
|
||||||
|
- Point class
|
||||||
|
|
||||||
|
- adding "features" such as "IsInTriangle", ... ?
|
||||||
|
|
||||||
|
- direct member access instead of getters?
|
||||||
|
|
||||||
|
91
Utility.h
Normal file
91
Utility.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef UTILITY_H
|
||||||
|
|
||||||
|
static float sign(float x, float y, float x1, float y1, float x2, float y2)
|
||||||
|
{
|
||||||
|
return (x - x2) * (y1 - y2) - (x1 - x2) * (y - y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float sign (Point &p1, Point &p2, Point &p3)
|
||||||
|
{
|
||||||
|
return (p1.x() - p3.x()) * (p2.y() - p3.y()) - (p2.x() - p3.x()) * (p1.y() - p3.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsPointInTriangle(Point &pt, Point &p1, Point &p2, Point &p3)
|
||||||
|
{
|
||||||
|
float d1 = sign(pt, p1, p2);
|
||||||
|
float d2 = sign(pt, p2, p3);
|
||||||
|
float d3 = sign(pt, p3, p1);
|
||||||
|
|
||||||
|
bool has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0);
|
||||||
|
bool has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0);
|
||||||
|
|
||||||
|
return !(has_neg && has_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float pDistance(float x, float y, float x1, float y1, float x2, float y2) {
|
||||||
|
|
||||||
|
float A = x - x1;
|
||||||
|
float B = y - y1;
|
||||||
|
float C = x2 - x1;
|
||||||
|
float D = y2 - y1;
|
||||||
|
|
||||||
|
float dot = A * C + B * D;
|
||||||
|
float len_sq = C * C + D * D;
|
||||||
|
float param = -1;
|
||||||
|
if (len_sq != 0) // in case of 0 length line
|
||||||
|
param = dot / len_sq;
|
||||||
|
|
||||||
|
float xx, yy;
|
||||||
|
if (param < 0) {
|
||||||
|
xx = x1;
|
||||||
|
yy = y1;
|
||||||
|
}
|
||||||
|
else if (param > 1) {
|
||||||
|
xx = x2;
|
||||||
|
yy = y2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
xx = x1 + param * C;
|
||||||
|
yy = y1 + param * D;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dx = x - xx;
|
||||||
|
float dy = y - yy;
|
||||||
|
return dx * dx + dy * dy;
|
||||||
|
//return sqrt(dx * dx + dy * dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SortForMinXMaxY (const Point& a, const Point& b)
|
||||||
|
{
|
||||||
|
if (a.x() != b.x())
|
||||||
|
{
|
||||||
|
return (a.x() < b.x());
|
||||||
|
}
|
||||||
|
return (a.y() > b.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool SortForMinYMaxX(const Point& a, const Point& b)
|
||||||
|
{
|
||||||
|
if (a.y() != b.y())
|
||||||
|
{
|
||||||
|
return (a.x() < b.x());
|
||||||
|
}
|
||||||
|
return (a.y() > b.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sortPoints (std::vector<Point>& pts)
|
||||||
|
{
|
||||||
|
std::sort(pts.begin(), pts.end(), SortForMinXMaxY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: what happens if all/more points are on hor/vert line? -> sort for x, than y should handle this
|
||||||
|
static std::pair<Point, Point> getMinMaxX(std::vector<Point>& pts)
|
||||||
|
{
|
||||||
|
// TODO: check if already sorted? assume array is sorted? call sort utility function???
|
||||||
|
//sortPoints(pts);
|
||||||
|
std::sort(pts.begin(), pts.end(), SortForMinXMaxY);
|
||||||
|
|
||||||
|
return std::make_pair(pts[0], pts[pts.size() - 1]);
|
||||||
|
}
|
||||||
|
#endif // UTILITY_H
|
37
main.cpp
37
main.cpp
@ -8,6 +8,7 @@
|
|||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
#include "Point.h" // TODO: check if there is a usable SFML or c++ class
|
#include "Point.h" // TODO: check if there is a usable SFML or c++ class
|
||||||
#include "Timing.h"
|
#include "Timing.h"
|
||||||
|
#include "Utility.h"
|
||||||
|
|
||||||
// TODOs:
|
// TODOs:
|
||||||
// - use SFML vec2 instead of Point class
|
// - use SFML vec2 instead of Point class
|
||||||
@ -41,10 +42,32 @@ int main (int argc, char **argv)
|
|||||||
std::cout << "generating random numbers..." << std::endl;
|
std::cout << "generating random numbers..." << std::endl;
|
||||||
//srand(static_cast <unsigned> (time(0)));
|
//srand(static_cast <unsigned> (time(0)));
|
||||||
srand(static_cast <unsigned> (0)); // fixed seed for testing
|
srand(static_cast <unsigned> (0)); // fixed seed for testing
|
||||||
|
|
||||||
|
// 2) rectangle
|
||||||
|
//float diff = (2.f * HEIGHT / valCount);
|
||||||
|
|
||||||
|
// 3) circle
|
||||||
|
//float rad = HEIGHT / 2; //8.0f;
|
||||||
|
//float deg = (float)(2 * 3.14159 / valCount);
|
||||||
|
|
||||||
|
float x = 0;
|
||||||
|
float y = 0;
|
||||||
for (int i = 0; i < valCount; ++i)
|
for (int i = 0; i < valCount; ++i)
|
||||||
{
|
{
|
||||||
float x = static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / WIDTH));
|
// 1) random generation
|
||||||
float y = static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / HEIGHT));
|
//x = OFFSET + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (WIDTH - OFFSET)));
|
||||||
|
//y = OFFSET + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (HEIGHT - OFFSET)));
|
||||||
|
x = OFFSET + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (WIDTH - 2*OFFSET)));
|
||||||
|
y = OFFSET + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (HEIGHT - 2*OFFSET)));
|
||||||
|
|
||||||
|
// 2) rectangle
|
||||||
|
//x = (i%2 == 0) ? OFFSET : WIDTH - OFFSET;
|
||||||
|
//y = diff/2 + (i/2) * diff;
|
||||||
|
|
||||||
|
// 3) position in circle around center, x/y plane
|
||||||
|
//x = WIDTH/2 + rad * cosf(i * deg);
|
||||||
|
//y = HEIGHT/2 + rad * sinf(i * deg);
|
||||||
|
|
||||||
points.push_back(Point(x, y));
|
points.push_back(Point(x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,7 +99,8 @@ int main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: need sort here?
|
// TODO: sort here, once and for all? xD
|
||||||
|
//sortPoints(points);
|
||||||
for (Point& pt : points)
|
for (Point& pt : points)
|
||||||
{
|
{
|
||||||
std::cout << "pt: " << pt.x() << ", " << pt.y() << std::endl;
|
std::cout << "pt: " << pt.x() << ", " << pt.y() << std::endl;
|
||||||
@ -84,9 +108,10 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
if (vis)
|
if (vis)
|
||||||
{
|
{
|
||||||
// TODO: use data as ctor argument? pointer?
|
// TEST to check SFML coordinate system
|
||||||
Display display;
|
//points.push_back(Point(0, 0));
|
||||||
display.setData(points);
|
|
||||||
|
Display display(points);
|
||||||
display.show();
|
display.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user