2011-06-22 21:29:41 +00:00
|
|
|
#include "graph.h"
|
2011-06-23 16:07:45 +00:00
|
|
|
#include "mathutils.h"
|
2011-06-23 17:54:28 +00:00
|
|
|
#include "debug.h"
|
2011-06-24 18:59:18 +00:00
|
|
|
#include <list>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cassert>
|
|
|
|
|
|
|
|
using std::list;
|
2011-06-23 01:54:35 +00:00
|
|
|
|
2011-06-23 21:28:49 +00:00
|
|
|
Graph::Graph(bool planar)
|
2011-06-23 01:54:35 +00:00
|
|
|
{
|
2011-06-23 21:28:49 +00:00
|
|
|
this->planar = planar;
|
2011-06-23 01:54:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Graph::~Graph()
|
|
|
|
{
|
|
|
|
for (list<Vertex*>::iterator cursor = vertices.begin();
|
|
|
|
cursor != vertices.end(); cursor++)
|
|
|
|
{
|
|
|
|
Vertex* v = *cursor;
|
|
|
|
delete v;
|
|
|
|
}
|
|
|
|
}
|
2011-06-22 21:29:41 +00:00
|
|
|
|
2011-07-01 16:24:52 +00:00
|
|
|
|
|
|
|
// In 3-space, this will be less useful, because we'll be clicking on the
|
|
|
|
// objects themselves... but we'll cross that bridge when we get there
|
|
|
|
bool Graph::point_in_vertex(int x, int y, int z)
|
2011-06-22 21:29:41 +00:00
|
|
|
{
|
2011-06-23 01:54:35 +00:00
|
|
|
for (list<Vertex*>::iterator cursor = vertices.begin();
|
2011-06-22 21:29:41 +00:00
|
|
|
cursor != vertices.end(); cursor++)
|
|
|
|
{
|
2011-06-23 16:36:40 +00:00
|
|
|
Vertex* v = *cursor;
|
2011-07-01 16:24:52 +00:00
|
|
|
if (MathUtils::distance(v->x, v->y, v->z, x, y, z) <= v->r)
|
|
|
|
return true;
|
2011-06-22 21:29:41 +00:00
|
|
|
}
|
|
|
|
|
2011-06-23 17:54:28 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-07-01 16:24:52 +00:00
|
|
|
Vertex * Graph::vertex_at(int x, int y, int z)
|
2011-06-23 21:28:49 +00:00
|
|
|
{
|
|
|
|
for (list<Vertex*>::iterator cursor = vertices.begin();
|
|
|
|
cursor != vertices.end(); cursor++)
|
|
|
|
{
|
|
|
|
Vertex* v = *cursor;
|
2011-07-01 16:24:52 +00:00
|
|
|
if (MathUtils::distance(v->x, v->y, v->z, x, y, z) <= v->r) return v;
|
2011-06-23 21:28:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-07-01 16:24:52 +00:00
|
|
|
bool Graph::vertex_would_overlap(int x, int y, int z, int r)
|
2011-06-23 17:54:28 +00:00
|
|
|
{
|
|
|
|
for (list<Vertex*>::iterator cursor = vertices.begin();
|
|
|
|
cursor != vertices.end(); cursor++)
|
|
|
|
{
|
|
|
|
Vertex* v = *cursor;
|
2011-07-01 16:24:52 +00:00
|
|
|
if (MathUtils::distance(v->x, v->y, v->z, x, y, z) <= v->r + r)
|
|
|
|
return true;
|
2011-06-23 17:54:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-27 22:10:24 +00:00
|
|
|
bool Graph::crosses_edge(Vertex* a, Vertex* b)
|
2011-06-23 17:54:28 +00:00
|
|
|
{
|
2011-06-27 22:10:24 +00:00
|
|
|
for (list<Vertex*>::iterator cursor = vertices.begin();
|
|
|
|
cursor != vertices.end(); cursor++)
|
2011-06-23 17:54:28 +00:00
|
|
|
{
|
2011-06-27 22:10:24 +00:00
|
|
|
Vertex* v = *cursor;
|
|
|
|
for (list<Vertex*>::iterator subcursor = v->neighbors.begin();
|
|
|
|
subcursor != v->neighbors.end(); subcursor++)
|
|
|
|
{
|
2011-06-28 00:32:29 +00:00
|
|
|
Vertex* w = *subcursor;
|
2011-06-27 22:10:24 +00:00
|
|
|
|
|
|
|
if (MathUtils::lines_intersect(a->x, a->y, b->x, b->y,
|
|
|
|
v->x, v->y, w->x, w->y))
|
|
|
|
return true;
|
|
|
|
}
|
2011-06-23 17:54:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2011-06-22 21:29:41 +00:00
|
|
|
}
|
|
|
|
|
2011-06-23 02:32:33 +00:00
|
|
|
|
2011-07-01 16:24:52 +00:00
|
|
|
bool Graph::add_vertex(int x, int y, int z, int r, int colour, int score, Vertex* src)
|
2011-06-22 21:29:41 +00:00
|
|
|
{
|
2011-07-01 16:24:52 +00:00
|
|
|
Vertex* v = new Vertex(x, y, z, r, colour, score);
|
2011-06-22 21:57:44 +00:00
|
|
|
|
2011-06-23 16:36:40 +00:00
|
|
|
// Make sure the nodes won't overlap
|
2011-07-01 16:24:52 +00:00
|
|
|
if (vertex_would_overlap(v->x, v->y, v->z, v->r))
|
2011-06-23 17:54:28 +00:00
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
2011-07-01 16:24:52 +00:00
|
|
|
fprintf(stderr, "debug: Graph::add_vertex(): failed to add due to vertex collision: x=%d, y=%d, z=%d, r=%d\n", v->x, v->y, v->z, v->r);
|
2011-06-23 17:54:28 +00:00
|
|
|
#endif
|
|
|
|
delete v;
|
2011-06-23 21:28:49 +00:00
|
|
|
return false;
|
2011-06-23 17:54:28 +00:00
|
|
|
}
|
2011-06-23 01:54:35 +00:00
|
|
|
|
2011-06-23 21:28:49 +00:00
|
|
|
if (src != NULL)
|
2011-06-23 01:54:35 +00:00
|
|
|
{
|
2011-06-27 22:10:24 +00:00
|
|
|
if (planar && crosses_edge(v, src))
|
2011-06-23 21:28:49 +00:00
|
|
|
{
|
2011-06-23 17:54:28 +00:00
|
|
|
#ifdef DEBUG
|
2011-06-29 02:14:55 +00:00
|
|
|
fprintf(stderr, "debug: Graph::add_vertex(): failed to add due to edge collision: x1=%d, y1=%d, x2=%d, y2=%d\n", v->x, v->y, src->x, src->y);
|
2011-06-23 17:54:28 +00:00
|
|
|
#endif
|
2011-06-23 21:28:49 +00:00
|
|
|
delete v;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-06-27 22:10:24 +00:00
|
|
|
v->neighbors.push_back(src);
|
|
|
|
src->neighbors.push_back(v);
|
2011-06-23 17:54:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
vertices.push_back(v);
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
2011-07-01 16:24:52 +00:00
|
|
|
fprintf(stderr, "debug: Graph::add_vertex(): added: x=%d, y=%d, z=%d, r=%d, score=%d, colour=%x\n", v->x, v->y, v->z, v->r, v->score, v->colour);
|
2011-06-23 17:54:28 +00:00
|
|
|
#endif
|
2011-06-23 21:28:49 +00:00
|
|
|
|
|
|
|
return true;
|
2011-06-22 21:29:41 +00:00
|
|
|
}
|
2011-06-23 16:46:32 +00:00
|
|
|
|
|
|
|
|
2011-06-24 15:03:40 +00:00
|
|
|
list<Vertex*> Graph::get_colour(int colour)
|
|
|
|
{
|
|
|
|
list<Vertex*> answer;
|
|
|
|
|
|
|
|
for (list<Vertex*>::iterator cursor = vertices.begin();
|
|
|
|
cursor != vertices.end(); cursor++)
|
|
|
|
{
|
|
|
|
Vertex* v = *cursor;
|
|
|
|
if (v->colour == colour) answer.push_back(v);
|
|
|
|
}
|
|
|
|
|
|
|
|
return answer;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-06-24 18:59:18 +00:00
|
|
|
void Graph::remove_vertex(Vertex* target)
|
|
|
|
{
|
2011-06-27 22:10:24 +00:00
|
|
|
list<Vertex*>::iterator cursor;
|
|
|
|
|
|
|
|
for (cursor = target->neighbors.begin(); cursor != target->neighbors.end();
|
|
|
|
cursor++)
|
2011-06-24 18:59:18 +00:00
|
|
|
{
|
2011-06-28 03:05:14 +00:00
|
|
|
list<Vertex*>::iterator subcursor = find((*cursor)->neighbors.begin(),
|
|
|
|
(*cursor)->neighbors.end(),
|
|
|
|
target);
|
|
|
|
assert(subcursor != (*cursor)->neighbors.end());
|
|
|
|
(*cursor)->neighbors.erase(subcursor);
|
2011-06-24 18:59:18 +00:00
|
|
|
}
|
2011-06-27 22:10:24 +00:00
|
|
|
|
|
|
|
cursor = find(vertices.begin(), vertices.end(), target);
|
|
|
|
assert(cursor != vertices.end());
|
|
|
|
vertices.erase(cursor);
|
2011-06-24 18:59:18 +00:00
|
|
|
delete target;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-07-01 16:24:52 +00:00
|
|
|
Vertex::Vertex(int x, int y, int z, int r, int colour, int score)
|
2011-06-24 18:59:18 +00:00
|
|
|
{
|
|
|
|
this->x = x;
|
|
|
|
this->y = y;
|
2011-07-01 16:24:52 +00:00
|
|
|
this->z = z;
|
2011-06-24 18:59:18 +00:00
|
|
|
this->r = r;
|
|
|
|
this->colour = colour;
|
|
|
|
this->score = score;
|
|
|
|
}
|