Put framework in place for dealing with graphs in 3 dimensions

This commit is contained in:
Anna Rose 2011-07-01 12:24:52 -04:00
parent 7b4b3ba76e
commit 36414a6996
7 changed files with 46 additions and 34 deletions

View File

@ -52,7 +52,7 @@ bool DrawUtils::draw(SDL_Surface* dest, SDL_Surface* drawable, int x, int y,
return true; return true;
} }
#include "debug.h"
void DrawUtils::draw_line(SDL_Surface* dest, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint16 width, Uint32 colour) void DrawUtils::draw_line(SDL_Surface* dest, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint16 width, Uint32 colour)
{ {
float dx, dy, len; float dx, dy, len;
@ -60,7 +60,7 @@ void DrawUtils::draw_line(SDL_Surface* dest, Sint16 x1, Sint16 y1, Sint16 x2, Si
SDL_Rect pen; SDL_Rect pen;
len = MathUtils::distance(x1,y1,x2,y2); len = MathUtils::distance(x1, y1, 0, x2, y2, 0);
// dx and dy represent the amount we move // dx and dy represent the amount we move
// each step in our drawing loop // each step in our drawing loop

View File

@ -38,7 +38,7 @@ void GameData::toggle_turn()
void GameData::do_vertex(int x, int y, int r) void GameData::do_vertex(int x, int y, int r)
{ {
if (current != NULL && if (current != NULL &&
(MathUtils::distance(current->x, current->y, x, y) (MathUtils::distance(current->x, current->y, current->z, x, y, 0)
> get_range())) > get_range()))
{ {
select_vertex(x, y); select_vertex(x, y);
@ -51,12 +51,12 @@ void GameData::do_vertex(int x, int y, int r)
if (mode == MODE_MOVE) if (mode == MODE_MOVE)
{ {
if (point_in_vertex(x, y)) select_vertex(x, y); if (point_in_vertex(x, y, 0)) select_vertex(x, y);
else add_vertex(x, y, r, colour); else add_vertex(x, y, 0, r, colour);
} }
if (mode == MODE_ATTACK) if (mode == MODE_ATTACK)
{ {
Vertex* v = vertex_at(x, y); Vertex* v = vertex_at(x, y, 0);
if (v == NULL) return; if (v == NULL) return;
if (v->colour == colour) select_vertex(x, y); if (v->colour == colour) select_vertex(x, y);
@ -72,7 +72,7 @@ void GameData::select_vertex(int x, int y)
cursor != vertices.end(); cursor++) cursor != vertices.end(); cursor++)
{ {
Vertex* v = *cursor; Vertex* v = *cursor;
if ((MathUtils::distance(v->x, v->y, x, y) <= v->r) && if ((MathUtils::distance(v->x, v->y, v->z, x, y, 0) <= v->r) &&
(v->colour == PLAYER1_COLOUR && player == PLAYER1 || (v->colour == PLAYER1_COLOUR && player == PLAYER1 ||
v->colour == PLAYER2_COLOUR && player == PLAYER2)) v->colour == PLAYER2_COLOUR && player == PLAYER2))
{ {
@ -83,7 +83,7 @@ void GameData::select_vertex(int x, int y)
} }
bool GameData::add_vertex(int x, int y, int r, int colour) bool GameData::add_vertex(int x, int y, int z, int r, int colour)
{ {
if (mode == MODE_ATTACK) return false; if (mode == MODE_ATTACK) return false;
@ -93,7 +93,7 @@ bool GameData::add_vertex(int x, int y, int r, int colour)
if ((player == PLAYER1 && !player1_played) || if ((player == PLAYER1 && !player1_played) ||
(player == PLAYER2 && !player2_played)) (player == PLAYER2 && !player2_played))
{ {
Graph::add_vertex(x, y, r, colour, 10); Graph::add_vertex(x, y, z, r, colour, 10);
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "debug: GameData::add_vertex(): strength=%2.f\n", fprintf(stderr, "debug: GameData::add_vertex(): strength=%2.f\n",
calculate_strength(*(vertices.rbegin()))); calculate_strength(*(vertices.rbegin())));
@ -106,7 +106,7 @@ bool GameData::add_vertex(int x, int y, int r, int colour)
return false; return false;
} }
if (Graph::add_vertex(x, y, r, colour, 10, current)) if (Graph::add_vertex(x, y, z, r, colour, 10, current))
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "debug: GameData::add_vertex(): strength=%.2f\n", fprintf(stderr, "debug: GameData::add_vertex(): strength=%.2f\n",
@ -191,7 +191,9 @@ int GameData::get_range(Vertex* node)
cursor != neighbors.end(); cursor++) cursor != neighbors.end(); cursor++)
{ {
Vertex* v = *cursor; Vertex* v = *cursor;
range -= (100 - MathUtils::distance(v->x, v->y, node->x, node->y)) / 2; range -= (100 - MathUtils::distance(v->x, v->y, v->z,
node->x, node->y, node->z))
/ 2;
} }
if (range < 0) range = 0; if (range < 0) range = 0;
return range; return range;

View File

@ -27,7 +27,7 @@ class GameData : public Graph
void select_vertex(int x, int y); void select_vertex(int x, int y);
void attack_vertex(Vertex* target); void attack_vertex(Vertex* target);
bool add_vertex(int x, int y, int r, int colour); bool add_vertex(int x, int y, int z, int r, int colour);
Mode get_mode() const { return mode; } Mode get_mode() const { return mode; }
Mode set_mode(Mode m) { mode = m; } Mode set_mode(Mode m) { mode = m; }

View File

@ -22,39 +22,44 @@ Graph::~Graph()
} }
} }
bool Graph::point_in_vertex(int x, int y)
// 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)
{ {
for (list<Vertex*>::iterator cursor = vertices.begin(); for (list<Vertex*>::iterator cursor = vertices.begin();
cursor != vertices.end(); cursor++) cursor != vertices.end(); cursor++)
{ {
Vertex* v = *cursor; Vertex* v = *cursor;
if (MathUtils::distance(v->x, v->y, x, y) <= v->r) return true; if (MathUtils::distance(v->x, v->y, v->z, x, y, z) <= v->r)
return true;
} }
return false; return false;
} }
Vertex * Graph::vertex_at(int x, int y) Vertex * Graph::vertex_at(int x, int y, int z)
{ {
for (list<Vertex*>::iterator cursor = vertices.begin(); for (list<Vertex*>::iterator cursor = vertices.begin();
cursor != vertices.end(); cursor++) cursor != vertices.end(); cursor++)
{ {
Vertex* v = *cursor; Vertex* v = *cursor;
if (MathUtils::distance(v->x, v->y, x, y) <= v->r) return v; if (MathUtils::distance(v->x, v->y, v->z, x, y, z) <= v->r) return v;
} }
return NULL; return NULL;
} }
bool Graph::vertex_would_overlap(int x, int y, int r) bool Graph::vertex_would_overlap(int x, int y, int z, int r)
{ {
for (list<Vertex*>::iterator cursor = vertices.begin(); for (list<Vertex*>::iterator cursor = vertices.begin();
cursor != vertices.end(); cursor++) cursor != vertices.end(); cursor++)
{ {
Vertex* v = *cursor; Vertex* v = *cursor;
if (MathUtils::distance(v->x, v->y, x, y) <= v->r + r) return true; if (MathUtils::distance(v->x, v->y, v->z, x, y, z) <= v->r + r)
return true;
} }
return false; return false;
@ -82,15 +87,15 @@ bool Graph::crosses_edge(Vertex* a, Vertex* b)
} }
bool Graph::add_vertex(int x, int y, int r, int colour, int score, Vertex* src) bool Graph::add_vertex(int x, int y, int z, int r, int colour, int score, Vertex* src)
{ {
Vertex* v = new Vertex(x, y, r, colour, score); Vertex* v = new Vertex(x, y, z, r, colour, score);
// Make sure the nodes won't overlap // Make sure the nodes won't overlap
if (vertex_would_overlap(v->x, v->y, v->r)) if (vertex_would_overlap(v->x, v->y, v->z, v->r))
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "debug: Graph::add_vertex(): failed to add due to vertex collision: x=%d, y=%d, r=%d\n", v->x, v->y, v->r); 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);
#endif #endif
delete v; delete v;
return false; return false;
@ -114,7 +119,7 @@ bool Graph::add_vertex(int x, int y, int r, int colour, int score, Vertex* src)
vertices.push_back(v); vertices.push_back(v);
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "debug: Graph::add_vertex(): added: x=%d, y=%d, r=%d, score=%d, colour=%x\n", v->x, v->y, v->r, v->score, v->colour); 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);
#endif #endif
return true; return true;
@ -157,10 +162,11 @@ void Graph::remove_vertex(Vertex* target)
} }
Vertex::Vertex(int x, int y, int r, int colour, int score) Vertex::Vertex(int x, int y, int z, int r, int colour, int score)
{ {
this->x = x; this->x = x;
this->y = y; this->y = y;
this->z = z;
this->r = r; this->r = r;
this->colour = colour; this->colour = colour;
this->score = score; this->score = score;

13
graph.h
View File

@ -24,10 +24,11 @@ using std::list;
class Vertex class Vertex
{ {
public: public:
Vertex(int x, int y, int r, int colour = 0, int score = 0); Vertex(int x, int y, int z, int r, int colour = 0, int score = 0);
int x; int x;
int y; int y;
int z;
int r; int r;
int colour; int colour;
int score; int score;
@ -45,10 +46,10 @@ class Graph
list<Vertex*> get_vertices() const { return vertices; } list<Vertex*> get_vertices() const { return vertices; }
list<Vertex*> get_colour(int colour); list<Vertex*> get_colour(int colour);
bool point_in_vertex(int x, int y); bool point_in_vertex(int x, int y, int z);
Vertex * vertex_at(int x, int y); Vertex * vertex_at(int x, int y, int z);
virtual bool add_vertex(int x, int y, int r, int colour = 0, int score = 0, virtual bool add_vertex(int x, int y, int z, int r, int colour = 0,
Vertex* src=NULL); int score = 0, Vertex* src=NULL);
void remove_vertex(Vertex* target); void remove_vertex(Vertex* target);
bool is_planar() const { return planar; } bool is_planar() const { return planar; }
@ -58,7 +59,7 @@ class Graph
list<Vertex*> vertices; list<Vertex*> vertices;
private: private:
bool vertex_would_overlap(int x, int y, int r); bool vertex_would_overlap(int x, int y, int z, int r);
bool crosses_edge(Vertex* a, Vertex* b); bool crosses_edge(Vertex* a, Vertex* b);
bool planar; bool planar;
}; };

View File

@ -1,11 +1,13 @@
#include "mathutils.h" #include "mathutils.h"
#include <math.h> #include <math.h>
float MathUtils::distance(float x1, float y1, float x2, float y2) float MathUtils::distance(float x1, float y1, float z1,
float x2, float y2, float z2)
{ {
float dy = y2 - y1;
float dx = x2 - x1; float dx = x2 - x1;
return sqrt(dy*dy + dx*dx); float dy = y2 - y1;
float dz = z2 - z1;
return sqrt(dx*dx + dy*dy + dz*dz);
} }
// Algorithm found at http://paulbourke.net/geometry/lineline2d/ // Algorithm found at http://paulbourke.net/geometry/lineline2d/

View File

@ -8,7 +8,8 @@ class MathUtils
{ {
public: public:
// returns the cartesian distance of two points // returns the cartesian distance of two points
static float distance(float x1, float y1, float x2, float y2); static float distance(float x1, float y1, float z1, float x2, float y2,
float z2);
static bool lines_intersect(int x1, int y1, int x2, int y2, static bool lines_intersect(int x1, int y1, int x2, int y2,
int x3, int y3, int x4, int y4); int x3, int y3, int x4, int y4);