2010-01-22 21:03:43 +01:00
|
|
|
/*
|
|
|
|
* Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
|
2010-01-17 17:41:09 +01:00
|
|
|
* http://code.google.com/p/poly2tri/
|
|
|
|
*
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
* are permitted provided that the following conditions are met:
|
|
|
|
*
|
|
|
|
* * Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
|
|
* and/or other materials provided with the distribution.
|
|
|
|
* * Neither the name of Poly2Tri nor the names of its contributors may be
|
|
|
|
* used to endorse or promote products derived from this software without specific
|
|
|
|
* prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <GL/glfw.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <fstream>
|
|
|
|
#include <string>
|
|
|
|
#include <sstream>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <iterator>
|
|
|
|
#include <iostream>
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
#include "../poly2tri/poly2tri.h"
|
|
|
|
|
|
|
|
|
|
|
|
void Init();
|
|
|
|
void ShutDown(int return_code);
|
2010-01-19 23:23:38 +01:00
|
|
|
void MainLoop(const double zoom);
|
|
|
|
void Draw(const double zoom);
|
2010-01-20 18:25:10 +01:00
|
|
|
void DrawMap(const double zoom);
|
2010-01-20 18:10:58 +01:00
|
|
|
void ConstrainedColor(bool constrain);
|
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
float rotate_y = 0,
|
|
|
|
rotate_z = 0;
|
|
|
|
const float rotations_per_tick = .2;
|
|
|
|
|
2010-01-22 20:52:28 +01:00
|
|
|
/// Screen center x
|
|
|
|
double cx = 0.0;
|
|
|
|
/// Screen center y
|
|
|
|
double cy = 0.0;
|
|
|
|
|
2010-01-20 18:25:10 +01:00
|
|
|
/// Constrained triangles
|
2010-01-20 18:10:58 +01:00
|
|
|
vector<Triangle*> triangles;
|
2010-01-20 18:25:10 +01:00
|
|
|
/// Triangle map
|
|
|
|
list<Triangle*> map;
|
2010-01-17 17:41:09 +01:00
|
|
|
|
2010-01-21 15:00:09 +01:00
|
|
|
double StringToDouble(const std::string& s)
|
|
|
|
{
|
2010-01-17 17:41:09 +01:00
|
|
|
std::istringstream i(s);
|
|
|
|
double x;
|
|
|
|
if (!(i >> x))
|
2010-01-21 15:00:09 +01:00
|
|
|
return 0;
|
2010-01-17 17:41:09 +01:00
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
2010-01-22 20:52:28 +01:00
|
|
|
bool draw_map = false;
|
2010-01-20 18:25:10 +01:00
|
|
|
|
2010-01-21 15:00:09 +01:00
|
|
|
int main(int argc, char* argv[])
|
|
|
|
{
|
2010-01-22 20:52:28 +01:00
|
|
|
if (argc != 5) {
|
|
|
|
cout << "Usage: p2t filename centerX centerY zoom" << endl;
|
2010-01-19 23:23:38 +01:00
|
|
|
return 1;
|
|
|
|
}
|
2010-01-21 15:00:09 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
// initialize random seed:
|
|
|
|
srand ( time(NULL) );
|
|
|
|
|
|
|
|
int a = 0;
|
|
|
|
int b = 2000;
|
|
|
|
|
|
|
|
for(int i = 0; i < num_points; i++) {
|
|
|
|
double x = rand() % (b - a - 1) + a + 1;
|
|
|
|
double y = rand() % (b - a - 1) + a + 1;
|
|
|
|
polyline[i] = Point(x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2010-01-22 20:52:28 +01:00
|
|
|
cx = atof(argv[2]);
|
|
|
|
cy = atof(argv[3]);
|
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
string line;
|
2010-01-21 15:00:09 +01:00
|
|
|
ifstream myfile(argv[1]);
|
2010-01-20 18:10:58 +01:00
|
|
|
vector<Point*> points;
|
2010-01-17 17:41:09 +01:00
|
|
|
if (myfile.is_open()) {
|
|
|
|
while (!myfile.eof()) {
|
2010-01-21 15:00:09 +01:00
|
|
|
getline(myfile, line);
|
|
|
|
if (line.size() == 0) {
|
2010-01-17 17:41:09 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
istringstream iss(line);
|
|
|
|
vector<string> tokens;
|
2010-01-21 15:00:09 +01:00
|
|
|
copy(istream_iterator<string>(iss), istream_iterator<string>(),
|
2010-01-17 17:41:09 +01:00
|
|
|
back_inserter<vector<string> >(tokens));
|
|
|
|
double x = StringToDouble(tokens[0]);
|
|
|
|
double y = StringToDouble(tokens[1]);
|
2010-01-20 18:10:58 +01:00
|
|
|
points.push_back(new Point(x, y));
|
2010-01-17 17:41:09 +01:00
|
|
|
}
|
|
|
|
myfile.close();
|
|
|
|
} else {
|
|
|
|
cout << "File not opened" << endl;
|
|
|
|
}
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
int num_points = points.size();
|
|
|
|
cout << "Number of points = " << num_points << endl;
|
2010-01-21 15:00:09 +01:00
|
|
|
|
|
|
|
Point** polyline = new Point *[num_points];
|
|
|
|
for (int i = 0; i < num_points; i++) {
|
2010-01-20 18:10:58 +01:00
|
|
|
polyline[i] = points[i];
|
2010-01-17 17:41:09 +01:00
|
|
|
}
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
Init();
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
// Perform triangulation
|
|
|
|
double init_time = glfwGetTime();
|
|
|
|
CDT * cdt = new CDT(polyline, num_points);
|
|
|
|
cdt->Triangulate();
|
|
|
|
double dt = glfwGetTime() - init_time;
|
|
|
|
cout << "Elapsed time (secs) = " << dt << endl;
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
triangles = cdt->GetTriangles();
|
2010-01-20 18:25:10 +01:00
|
|
|
map = cdt->GetMap();
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-22 20:52:28 +01:00
|
|
|
MainLoop(atof(argv[4]));
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
delete [] polyline;
|
|
|
|
ShutDown(0);
|
|
|
|
return 0;
|
|
|
|
}
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
void Init()
|
|
|
|
{
|
|
|
|
const int window_width = 800,
|
|
|
|
window_height = 600;
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
if (glfwInit() != GL_TRUE)
|
|
|
|
ShutDown(1);
|
|
|
|
// 800 x 600, 16 bit color, no depth, alpha or stencil buffers, windowed
|
|
|
|
if (glfwOpenWindow(window_width, window_height, 5, 6, 5, 0, 0, 0, GLFW_WINDOW) != GL_TRUE)
|
2010-01-21 15:00:09 +01:00
|
|
|
ShutDown(1);
|
|
|
|
|
2010-01-20 21:36:05 +01:00
|
|
|
glfwSetWindowTitle("Poly2Tri - C++");
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
2010-01-21 15:00:09 +01:00
|
|
|
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
2010-01-17 17:41:09 +01:00
|
|
|
}
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
void ShutDown(int return_code)
|
|
|
|
{
|
|
|
|
glfwTerminate();
|
|
|
|
exit(return_code);
|
|
|
|
}
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-19 23:23:38 +01:00
|
|
|
void MainLoop(const double zoom)
|
2010-01-17 17:41:09 +01:00
|
|
|
{
|
|
|
|
// the time of the previous frame
|
|
|
|
double old_time = glfwGetTime();
|
|
|
|
// this just loops as long as the program runs
|
|
|
|
bool running = true;
|
2010-01-21 15:00:09 +01:00
|
|
|
|
|
|
|
while (running) {
|
2010-01-17 17:41:09 +01:00
|
|
|
// calculate time elapsed, and the amount by which stuff rotates
|
|
|
|
double current_time = glfwGetTime(),
|
2010-01-21 15:00:09 +01:00
|
|
|
delta_rotate = (current_time - old_time) * rotations_per_tick * 360;
|
2010-01-17 17:41:09 +01:00
|
|
|
old_time = current_time;
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
// escape to quit, arrow keys to rotate view
|
|
|
|
// Check if ESC key was pressed or window was closed
|
2010-01-21 15:00:09 +01:00
|
|
|
running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam(GLFW_OPENED);
|
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
if (glfwGetKey(GLFW_KEY_LEFT) == GLFW_PRESS)
|
|
|
|
rotate_y += delta_rotate;
|
|
|
|
if (glfwGetKey(GLFW_KEY_RIGHT) == GLFW_PRESS)
|
|
|
|
rotate_y -= delta_rotate;
|
|
|
|
// z axis always rotates
|
|
|
|
rotate_z += delta_rotate;
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
// Draw the scene
|
2010-01-21 15:00:09 +01:00
|
|
|
if (draw_map) {
|
2010-01-20 18:25:10 +01:00
|
|
|
DrawMap(zoom);
|
|
|
|
} else {
|
|
|
|
Draw(zoom);
|
|
|
|
}
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-17 17:41:09 +01:00
|
|
|
// swap back and front buffers
|
|
|
|
glfwSwapBuffers();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-21 15:00:09 +01:00
|
|
|
void ResetZoom(double zoom, double cx, double cy, double width, double height)
|
|
|
|
{
|
|
|
|
double left = -width / zoom;
|
|
|
|
double right = width / zoom;
|
|
|
|
double bottom = -height / zoom;
|
|
|
|
double top = height / zoom;
|
|
|
|
|
|
|
|
// Reset viewport
|
|
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
glLoadIdentity();
|
|
|
|
|
|
|
|
// Reset ortho view
|
|
|
|
glOrtho(left, right, bottom, top, 1, -1);
|
|
|
|
glTranslatef(-cx, -cy, 0);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glLoadIdentity();
|
|
|
|
|
|
|
|
// Clear the screen
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
2010-01-17 17:41:09 +01:00
|
|
|
}
|
2010-01-20 18:25:10 +01:00
|
|
|
|
2010-01-21 15:00:09 +01:00
|
|
|
void Draw(const double zoom)
|
|
|
|
{
|
2010-01-17 17:41:09 +01:00
|
|
|
// reset zoom
|
2010-01-22 20:52:28 +01:00
|
|
|
Point center = Point(cx, cy);
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-19 23:23:38 +01:00
|
|
|
ResetZoom(zoom, center.x, center.y, 800, 600);
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-20 18:10:58 +01:00
|
|
|
for (int i = 0; i < triangles.size(); i++) {
|
|
|
|
Triangle& t = *triangles[i];
|
|
|
|
Point& a = *t.GetPoint(0);
|
|
|
|
Point& b = *t.GetPoint(1);
|
|
|
|
Point& c = *t.GetPoint(2);
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-20 21:36:05 +01:00
|
|
|
// Red
|
|
|
|
glColor3f(1, 0, 0);
|
2010-01-20 18:10:58 +01:00
|
|
|
|
2010-01-21 15:00:09 +01:00
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
glVertex2f(a.x, a.y);
|
|
|
|
glVertex2f(b.x, b.y);
|
|
|
|
glVertex2f(c.x, c.y);
|
|
|
|
glEnd();
|
2010-01-20 18:10:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-21 15:00:09 +01:00
|
|
|
void DrawMap(const double zoom)
|
|
|
|
{
|
2010-01-20 18:25:10 +01:00
|
|
|
// reset zoom
|
2010-01-22 20:52:28 +01:00
|
|
|
Point center = Point(cx, cy);
|
2010-01-21 15:00:09 +01:00
|
|
|
|
2010-01-20 18:25:10 +01:00
|
|
|
ResetZoom(zoom, center.x, center.y, 800, 600);
|
2010-01-21 15:00:09 +01:00
|
|
|
|
|
|
|
list<Triangle*>::iterator it;
|
2010-01-20 18:25:10 +01:00
|
|
|
for (it = map.begin(); it != map.end(); it++) {
|
|
|
|
Triangle& t = **it;
|
|
|
|
Point& a = *t.GetPoint(0);
|
|
|
|
Point& b = *t.GetPoint(1);
|
|
|
|
Point& c = *t.GetPoint(2);
|
2010-01-21 15:00:09 +01:00
|
|
|
|
|
|
|
ConstrainedColor(t.constrained_edge[2]);
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex2f(a.x, a.y);
|
|
|
|
glVertex2f(b.x, b.y);
|
2010-01-20 21:36:05 +01:00
|
|
|
glEnd( );
|
|
|
|
|
2010-01-21 15:00:09 +01:00
|
|
|
ConstrainedColor(t.constrained_edge[0]);
|
2010-01-20 21:36:05 +01:00
|
|
|
glBegin(GL_LINES);
|
2010-01-21 15:00:09 +01:00
|
|
|
glVertex2f(b.x, b.y);
|
|
|
|
glVertex2f(c.x, c.y);
|
2010-01-20 21:36:05 +01:00
|
|
|
glEnd( );
|
|
|
|
|
2010-01-21 15:00:09 +01:00
|
|
|
ConstrainedColor(t.constrained_edge[1]);
|
2010-01-20 21:36:05 +01:00
|
|
|
glBegin(GL_LINES);
|
2010-01-21 15:00:09 +01:00
|
|
|
glVertex2f(c.x, c.y);
|
|
|
|
glVertex2f(a.x, a.y);
|
2010-01-20 21:36:05 +01:00
|
|
|
glEnd( );
|
2010-01-20 18:25:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-21 15:00:09 +01:00
|
|
|
void ConstrainedColor(bool constrain)
|
|
|
|
{
|
|
|
|
if (constrain) {
|
2010-01-20 18:10:58 +01:00
|
|
|
// Green
|
|
|
|
glColor3f(0, 1, 0);
|
|
|
|
} else {
|
2010-01-17 17:41:09 +01:00
|
|
|
// Red
|
|
|
|
glColor3f(1, 0, 0);
|
|
|
|
}
|
|
|
|
}
|