zoomedit: C++ized Vertex

This commit is contained in:
neoraider 2007-09-16 14:07:03 +00:00
parent 2bdbece75f
commit 01e98d51fe
11 changed files with 196 additions and 138 deletions

View file

@ -1,4 +1,4 @@
bin_PROGRAMS = zoomedit bin_PROGRAMS = zoomedit
zoomedit_SOURCES = zoomedit.cpp window.cpp ui.cpp draw.cpp level.cpp geometry.cpp edit.cpp zoomedit_SOURCES = zoomedit.cpp window.cpp ui.cpp draw.cpp level.cpp geometry.cpp edit.cpp Vertex.cpp
zoomedit_CPPFLAGS = @GTK_CFLAGS@ zoomedit_CPPFLAGS = @GTK_CFLAGS@
zoomedit_LDADD = @GTK_LIBS@ zoomedit_LDADD = @GTK_LIBS@

View file

@ -51,7 +51,8 @@ PROGRAMS = $(bin_PROGRAMS)
am_zoomedit_OBJECTS = zoomedit-zoomedit.$(OBJEXT) \ am_zoomedit_OBJECTS = zoomedit-zoomedit.$(OBJEXT) \
zoomedit-window.$(OBJEXT) zoomedit-ui.$(OBJEXT) \ zoomedit-window.$(OBJEXT) zoomedit-ui.$(OBJEXT) \
zoomedit-draw.$(OBJEXT) zoomedit-level.$(OBJEXT) \ zoomedit-draw.$(OBJEXT) zoomedit-level.$(OBJEXT) \
zoomedit-geometry.$(OBJEXT) zoomedit-edit.$(OBJEXT) zoomedit-geometry.$(OBJEXT) zoomedit-edit.$(OBJEXT) \
zoomedit-Vertex.$(OBJEXT)
zoomedit_OBJECTS = $(am_zoomedit_OBJECTS) zoomedit_OBJECTS = $(am_zoomedit_OBJECTS)
zoomedit_DEPENDENCIES = zoomedit_DEPENDENCIES =
DEFAULT_INCLUDES = -I.@am__isrc@ DEFAULT_INCLUDES = -I.@am__isrc@
@ -169,7 +170,7 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@ target_alias = @target_alias@
top_builddir = @top_builddir@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
zoomedit_SOURCES = zoomedit.cpp window.cpp ui.cpp draw.cpp level.cpp geometry.cpp edit.cpp zoomedit_SOURCES = zoomedit.cpp window.cpp ui.cpp draw.cpp level.cpp geometry.cpp edit.cpp Vertex.cpp
zoomedit_CPPFLAGS = @GTK_CFLAGS@ zoomedit_CPPFLAGS = @GTK_CFLAGS@
zoomedit_LDADD = @GTK_LIBS@ zoomedit_LDADD = @GTK_LIBS@
all: config.h all: config.h
@ -260,6 +261,7 @@ mostlyclean-compile:
distclean-compile: distclean-compile:
-rm -f *.tab.c -rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-Vertex.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-draw.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-draw.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-edit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-edit.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-geometry.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-geometry.Po@am__quote@
@ -380,6 +382,20 @@ zoomedit-edit.obj: edit.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zoomedit-edit.obj `if test -f 'edit.cpp'; then $(CYGPATH_W) 'edit.cpp'; else $(CYGPATH_W) '$(srcdir)/edit.cpp'; fi` @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zoomedit-edit.obj `if test -f 'edit.cpp'; then $(CYGPATH_W) 'edit.cpp'; else $(CYGPATH_W) '$(srcdir)/edit.cpp'; fi`
zoomedit-Vertex.o: Vertex.cpp
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zoomedit-Vertex.o -MD -MP -MF $(DEPDIR)/zoomedit-Vertex.Tpo -c -o zoomedit-Vertex.o `test -f 'Vertex.cpp' || echo '$(srcdir)/'`Vertex.cpp
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/zoomedit-Vertex.Tpo $(DEPDIR)/zoomedit-Vertex.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Vertex.cpp' object='zoomedit-Vertex.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zoomedit-Vertex.o `test -f 'Vertex.cpp' || echo '$(srcdir)/'`Vertex.cpp
zoomedit-Vertex.obj: Vertex.cpp
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zoomedit-Vertex.obj -MD -MP -MF $(DEPDIR)/zoomedit-Vertex.Tpo -c -o zoomedit-Vertex.obj `if test -f 'Vertex.cpp'; then $(CYGPATH_W) 'Vertex.cpp'; else $(CYGPATH_W) '$(srcdir)/Vertex.cpp'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/zoomedit-Vertex.Tpo $(DEPDIR)/zoomedit-Vertex.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Vertex.cpp' object='zoomedit-Vertex.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o zoomedit-Vertex.obj `if test -f 'Vertex.cpp'; then $(CYGPATH_W) 'Vertex.cpp'; else $(CYGPATH_W) '$(srcdir)/Vertex.cpp'; fi`
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \ unique=`for i in $$list; do \

33
Vertex.cpp Normal file
View file

@ -0,0 +1,33 @@
#include "Vertex.h"
#include <math.h>
double Vertex::distanceSq(const Vertex &v) const {
return (x - v.x)*(x - v.x) + (y - v.y)*(y - v.y);
}
double Vertex::distance(const Vertex &v) const {
return sqrt(distanceSq(v));
}
Vertex Vertex::operator+(const Vertex &v) const {
return Vertex(x + v.x, y + v.y);
}
Vertex Vertex::operator-(const Vertex &v) const {
return Vertex(x - v.x, y - v.y);
}
Vertex& Vertex::operator+=(const Vertex &v) {
x += v.x;
y += v.y;
return *this;
}
Vertex& Vertex::operator-=(const Vertex &v) {
x -= v.x;
y -= v.y;
return *this;
}

31
Vertex.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef VERTEX_H_
#define VERTEX_H_
class Vertex {
private:
double x, y;
public:
Vertex() {x = y = 0.0;}
Vertex(const Vertex &v) {x = v.x; y = v.y;}
Vertex(double x, double y) {this->x = x; this->y = y;}
double getX() const {return x;}
void setX(double x) {this->x = x;}
double getY() const {return y;}
void setY(double y) {this->y = y;}
void setLocation(const Vertex &v) {x = v.x; y = v.y;}
void setLocation(double x, double y) {this->x = x; this->y = y;}
double distanceSq(const Vertex &v) const;
double distance(const Vertex &v) const;
Vertex operator+(const Vertex &v) const;
Vertex operator-(const Vertex &v) const;
Vertex& operator+=(const Vertex &v);
Vertex& operator-=(const Vertex &v);
};
#endif /*VERTEX_H_*/

View file

@ -85,7 +85,7 @@ static void polygon2path(cairo_t *cr, const POLYGON *polygon, const RECTANGLE *r
cairo_new_sub_path(cr); cairo_new_sub_path(cr);
for(i = 0; i < polygon2.nVertices; i++) { for(i = 0; i < polygon2.nVertices; i++) {
cairo_line_to(cr, polygon2.vertices[i].x, polygon2.vertices[i].y); cairo_line_to(cr, polygon2.vertices[i].getX(), polygon2.vertices[i].getY());
} }
if(close) if(close)
@ -97,7 +97,7 @@ static void polygon2path(cairo_t *cr, const POLYGON *polygon, const RECTANGLE *r
gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) { gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
cairo_t *cr; cairo_t *cr;
VERTEX v1 = {-1, -1}, v2 = {widget->allocation.width+1, widget->allocation.height+1}; Vertex v1(-1, -1), v2(widget->allocation.width+1, widget->allocation.height+1);
RECTANGLE rect; RECTANGLE rect;
gboolean vertexOk; gboolean vertexOk;
static GdkPixmap *pixmap = NULL; static GdkPixmap *pixmap = NULL;
@ -112,10 +112,10 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
viewToImage(&v1); viewToImage(&v1);
viewToImage(&v2); viewToImage(&v2);
rect.x = v1.x; rect.x = v1.getX();
rect.y = v1.y; rect.y = v1.getY();
rect.width = v2.x-v1.x; rect.width = v2.getX()-v1.getX();
rect.height = v2.y-v1.y; rect.height = v2.getY()-v1.getY();
if(pixmap == NULL || fabs(lastImageWidth - getImageWidth()) >= 0.000001 || fabs(lastImageHeight - getImageHeight()) >= 0.000001 || if(pixmap == NULL || fabs(lastImageWidth - getImageWidth()) >= 0.000001 || fabs(lastImageHeight - getImageHeight()) >= 0.000001 ||
lastWidth != widget->allocation.width || lastHeight != widget->allocation.height || lastEditMode != getEditMode() || repaint) lastWidth != widget->allocation.width || lastHeight != widget->allocation.height || lastEditMode != getEditMode() || repaint)
@ -205,7 +205,7 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
vertexOk = isVertexOk(getHoveredVertex()); vertexOk = isVertexOk(getHoveredVertex());
if(vertexOk) if(vertexOk)
cairo_line_to(cr, getHoveredVertex()->x, getHoveredVertex()->y); cairo_line_to(cr, getHoveredVertex()->getX(), getHoveredVertex()->getY());
} }
cairo_set_line_width(cr, 2.0/scale); cairo_set_line_width(cr, 2.0/scale);
@ -218,8 +218,8 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
cairo_set_source_rgba(cr, 1.0, 0.3, 0.3, 0.7); cairo_set_source_rgba(cr, 1.0, 0.3, 0.3, 0.7);
i = getActiveRoom()->polygon.nVertices - 1; i = getActiveRoom()->polygon.nVertices - 1;
cairo_move_to(cr, getActiveRoom()->polygon.vertices[i].x, getActiveRoom()->polygon.vertices[i].y); cairo_move_to(cr, getActiveRoom()->polygon.vertices[i].getX(), getActiveRoom()->polygon.vertices[i].getY());
cairo_line_to(cr, getHoveredVertex()->x, getHoveredVertex()->y); cairo_line_to(cr, getHoveredVertex()->getX(), getHoveredVertex()->getY());
cairo_stroke(cr); cairo_stroke(cr);
} }
@ -240,14 +240,14 @@ void setScale(double s) {
repaint = TRUE; repaint = TRUE;
} }
void imageToView(VERTEX *v) { void imageToView(Vertex *v) {
v->x = v->x*scale+getImageWidth()/2-xTranslate; v->setX(v->getX()*scale+getImageWidth()/2-xTranslate);
v->y = v->y*scale+getImageHeight()/2-yTranslate; v->setY(v->getY()*scale+getImageHeight()/2-yTranslate);
} }
void viewToImage(VERTEX *v) { void viewToImage(Vertex *v) {
v->x = (v->x-getImageWidth()/2+xTranslate)/scale; v->setX((v->getX()-getImageWidth()/2+xTranslate)/scale);
v->y = (v->y-getImageHeight()/2+yTranslate)/scale; v->setY((v->getY()-getImageHeight()/2+yTranslate)/scale);
} }
double getImageWidth() { double getImageWidth() {
@ -258,8 +258,8 @@ double getImageWidth() {
if(level) { if(level) {
for(i = 0; i < level->nRooms; i++) { for(i = 0; i < level->nRooms; i++) {
for(j = 0; j < level->rooms[i].polygon.nVertices; j++) { for(j = 0; j < level->rooms[i].polygon.nVertices; j++) {
min = MIN(min, level->rooms[i].polygon.vertices[j].x); min = MIN(min, level->rooms[i].polygon.vertices[j].getX());
max = MAX(max, level->rooms[i].polygon.vertices[j].x); max = MAX(max, level->rooms[i].polygon.vertices[j].getX());
} }
} }
} }
@ -275,8 +275,8 @@ double getImageHeight() {
if(level) { if(level) {
for(i = 0; i < level->nRooms; i++) { for(i = 0; i < level->nRooms; i++) {
for(j = 0; j < level->rooms[i].polygon.nVertices; j++) { for(j = 0; j < level->rooms[i].polygon.nVertices; j++) {
min = MIN(min, level->rooms[i].polygon.vertices[j].y); min = MIN(min, level->rooms[i].polygon.vertices[j].getY());
max = MAX(max, level->rooms[i].polygon.vertices[j].y); max = MAX(max, level->rooms[i].polygon.vertices[j].getY());
} }
} }
} }

4
draw.h
View file

@ -10,8 +10,8 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data);
double getScale(); double getScale();
void setScale(double s); void setScale(double s);
void imageToView(VERTEX *v); void imageToView(Vertex *v);
void viewToImage(VERTEX *v); void viewToImage(Vertex *v);
double getImageWidth(); double getImageWidth();
double getImageHeight(); double getImageHeight();

View file

@ -9,7 +9,7 @@ static int editMode = EDIT_MODE_VIEW;
static ROOM *activeRoom = NULL; static ROOM *activeRoom = NULL;
static ROOM *hoveredRoom = NULL; static ROOM *hoveredRoom = NULL;
static VERTEX hoveredVertex; static Vertex hoveredVertex;
static int hasHoveredVertex = 0; static int hasHoveredVertex = 0;
int getEditMode() { int getEditMode() {
@ -31,12 +31,12 @@ void setActiveRoom(ROOM *room) {
} }
} }
VERTEX *getHoveredVertex() { Vertex *getHoveredVertex() {
if(hasHoveredVertex) return &hoveredVertex; if(hasHoveredVertex) return &hoveredVertex;
else return NULL; else return NULL;
} }
void setHoveredVertex(VERTEX *v) { void setHoveredVertex(Vertex *v) {
int i; int i;
LEVEL *l; LEVEL *l;
@ -49,8 +49,8 @@ void setHoveredVertex(VERTEX *v) {
for(i = 0; i < l->nRooms; i++) { for(i = 0; i < l->nRooms; i++) {
if(vertexInPolygon(v, &l->rooms[i].polygon)) { if(vertexInPolygon(v, &l->rooms[i].polygon)) {
hoveredRoom = &l->rooms[i]; //hoveredRoom = &l->rooms[i];
break; //break;
} }
} }
} }
@ -106,7 +106,7 @@ static int isLineOk(LINE *l) {
return 1; return 1;
} }
int isVertexOk(VERTEX *v) { int isVertexOk(Vertex *v) {
LEVEL *lvl = getLevel(); LEVEL *lvl = getLevel();
LINE l; LINE l;
int i; int i;

6
edit.h
View file

@ -18,10 +18,10 @@ void endAddMode();
ROOM *getHoveredRoom(); ROOM *getHoveredRoom();
VERTEX *getHoveredVertex(); Vertex *getHoveredVertex();
void setHoveredVertex(VERTEX *v); void setHoveredVertex(Vertex *v);
int isVertexOk(VERTEX *v); int isVertexOk(Vertex *v);
int isPolygonOk(POLYGON *polygon); int isPolygonOk(POLYGON *polygon);
#endif /*EDIT_H_*/ #endif /*EDIT_H_*/

View file

@ -4,20 +4,20 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
void addVertex(VERTEX_LIST *list, const VERTEX *v) { void addVertex(VERTEX_LIST *list, const Vertex *v) {
list->nVertices++; list->nVertices++;
list->vertices = (VERTEX*)realloc(list->vertices, list->nVertices*sizeof(VERTEX)); list->vertices = (Vertex*)realloc(list->vertices, list->nVertices*sizeof(Vertex));
list->vertices[list->nVertices-1] = *v; list->vertices[list->nVertices-1] = *v;
} }
void insertVertex(VERTEX_LIST *list, const VERTEX *v, unsigned int n) { void insertVertex(VERTEX_LIST *list, const Vertex *v, unsigned int n) {
int i; int i;
if(n > list->nVertices) if(n > list->nVertices)
n = list->nVertices; n = list->nVertices;
list->nVertices++; list->nVertices++;
list->vertices = (VERTEX*)realloc(list->vertices, list->nVertices*sizeof(VERTEX)); list->vertices = (Vertex*)realloc(list->vertices, list->nVertices*sizeof(Vertex));
for(i = list->nVertices-1; i > n; i--) for(i = list->nVertices-1; i > n; i--)
list->vertices[i] = list->vertices[i-1]; list->vertices[i] = list->vertices[i-1];
@ -33,72 +33,64 @@ void deleteVertex(VERTEX_LIST *list, unsigned int n) {
for(i = n; i < list->nVertices; i++) for(i = n; i < list->nVertices; i++)
list->vertices[i] = list->vertices[i+1]; list->vertices[i] = list->vertices[i+1];
list->vertices = (VERTEX*)realloc(list->vertices, list->nVertices*sizeof(VERTEX)); list->vertices = (Vertex*)realloc(list->vertices, list->nVertices*sizeof(Vertex));
} }
double vertexDistanceSquare(const VERTEX *v1, const VERTEX *v2) {
return (v1->x-v2->x)*(v1->x-v2->x) + (v1->y-v2->y)*(v1->y-v2->y);
}
double vertexDistance(const VERTEX *v1, const VERTEX *v2) { int vertexOnLine(const Vertex *v, const LINE *l) {
return sqrt(vertexDistanceSquare(v1, v2)); if(l->v1.getX() == l->v2.getX() && l->v1.getY() == l->v2.getY()) {
} if(l->v1.getX() == v->getX() && l->v1.getY() == v->getY()) return 1;
int vertexOnLine(const VERTEX *v, const LINE *l) {
if(l->v1.x == l->v2.x && l->v1.y == l->v2.y) {
if(l->v1.x == v->x && l->v1.y == v->y) return 1;
else return 0; else return 0;
} }
if(l->v1.x == l->v2.x) { if(l->v1.getX() == l->v2.getX()) {
if(l->v1.x != v->x) return 0; if(l->v1.getX() != v->getX()) return 0;
else if(v->y >= MIN(l->v1.y, l->v2.y) && v->y <= MAX(l->v1.y, l->v2.y)) return 1; else if(v->getY() >= MIN(l->v1.getY(), l->v2.getY()) && v->getY() <= MAX(l->v1.getY(), l->v2.getY())) return 1;
else return 1; else return 1;
} }
if(l->v1.y == l->v2.y) { if(l->v1.getY() == l->v2.getY()) {
if(l->v1.y != v->y) return 0; if(l->v1.getY() != v->getY()) return 0;
else if(v->x >= MIN(l->v1.x, l->v2.x) && v->x <= MAX(l->v1.x, l->v2.x)) return 1; else if(v->getX() >= MIN(l->v1.getX(), l->v2.getX()) && v->getX() <= MAX(l->v1.getX(), l->v2.getX())) return 1;
else return 1; else return 1;
} }
if((v->x-l->v1.x)/(l->v2.x-l->v1.x) - (v->y-l->v1.y)/(l->v2.y-l->v1.y) == 0) return 1; if((v->getX()-l->v1.getX())/(l->v2.getX()-l->v1.getX()) - (v->getY()-l->v1.getY())/(l->v2.getY()-l->v1.getY()) == 0) return 1;
else return 0; else return 0;
} }
int vertexInRect(const VERTEX *v, const RECTANGLE *rect) { int vertexInRect(const Vertex *v, const RECTANGLE *rect) {
int ret = EDGE_NONE; int ret = EDGE_NONE;
if(v->x < rect->x) ret |= EDGE_LEFT; if(v->getX() < rect->x) ret |= EDGE_LEFT;
else if(v->x >= rect->x+rect->width) ret |= EDGE_RIGHT; else if(v->getX() >= rect->x+rect->width) ret |= EDGE_RIGHT;
if(v->y < rect->y) ret |= EDGE_TOP; if(v->getY() < rect->y) ret |= EDGE_TOP;
else if(v->y >= rect->y+rect->height) ret |= EDGE_BOTTOM; else if(v->getY() >= rect->y+rect->height) ret |= EDGE_BOTTOM;
return ret; return ret;
} }
static int quadrant(VERTEX *v) { static int quadrant(Vertex *v) {
if(v->x > 0 && v->y >= 0) return 1; if(v->getX() > 0 && v->getY() >= 0) return 1;
if(v->x >= 0 && v->y < 0) return 2; if(v->getX() >= 0 && v->getY() < 0) return 2;
if(v->x < 0 && v->y <= 0) return 3; if(v->getX() < 0 && v->getY() <= 0) return 3;
if(v->x <= 0 && v->y > 0) return 4; if(v->getX() <= 0 && v->getY() > 0) return 4;
return 0; return 0;
} }
gboolean vertexInPolygon(const VERTEX *v, const POLYGON *p) { gboolean vertexInPolygon(const Vertex *v, const POLYGON *p) {
int d = 0, i, li; int d = 0, i, li;
int q, ql, q2; int q, ql, q2;
LINE d1 = {{-1, -1}, {1, 1}}; LINE d1 = {Vertex(-1, -1), Vertex(1, 1)};
LINE d2 = {{-1, 1}, {1, -1}}; LINE d2 = {Vertex(-1, 1), Vertex(1, -1)};
LINE l; LINE l;
VERTEX v2; Vertex v2;
if(p->nVertices == 0) return FALSE; if(p->nVertices == 0) return FALSE;
v2.x = p->vertices[p->nVertices-1].x - v->x; v2 = p->vertices[p->nVertices-1] - *v;
v2.y = p->vertices[p->nVertices-1].y - v->y;
q = quadrant(&v2); q = quadrant(&v2);
if(q == 0) return TRUE; if(q == 0) return TRUE;
@ -106,9 +98,8 @@ gboolean vertexInPolygon(const VERTEX *v, const POLYGON *p) {
for(i = 0; i < p->nVertices; i++) { for(i = 0; i < p->nVertices; i++) {
ql = q; ql = q;
v2.x = p->vertices[i].x - v->x;
v2.y = p->vertices[i].y - v->y; v2 = p->vertices[i] - *v;
q = quadrant(&v2);
if(q == 0) return TRUE; if(q == 0) return TRUE;
@ -124,9 +115,7 @@ gboolean vertexInPolygon(const VERTEX *v, const POLYGON *p) {
d--; d--;
break; break;
default: default:
l.v1.x = p->vertices[(i>0)?i-1:p->nVertices-1].x - v->x; l.v1 = p->vertices[(i>0)?i-1:p->nVertices-1] - *v;
l.v1.y = p->vertices[(i>0)?i-1:p->nVertices-1].y - v->y;
l.v2 = v2; l.v2 = v2;
if(q == 1 || q == 3) { if(q == 1 || q == 3) {
@ -158,7 +147,7 @@ double polygonPerimeter(const POLYGON *p) {
double d = 0.0; double d = 0.0;
for(i = 0; i < p->nVertices; i++) for(i = 0; i < p->nVertices; i++)
d += vertexDistance(&p->vertices[i], &p->vertices[(i+1)%p->nVertices]); d += p->vertices[i].distance(p->vertices[(i+1)%p->nVertices]);
return d; return d;
} }
@ -168,19 +157,19 @@ double polygonArea(const POLYGON *p) {
double d = 0.0; double d = 0.0;
for(i = 0; i < p->nVertices; i++) for(i = 0; i < p->nVertices; i++)
d += (p->vertices[(i+1)%p->nVertices].x+p->vertices[i].x)*(p->vertices[(i+1)%p->nVertices].y-p->vertices[i].y); d += (p->vertices[(i+1)%p->nVertices].getX()+p->vertices[i].getX())*(p->vertices[(i+1)%p->nVertices].getY()-p->vertices[i].getY());
return fabs(d/2); return fabs(d/2);
} }
int lineIntersection(const LINE *la, const LINE *lb, VERTEX *v) { int lineIntersection(const LINE *la, const LINE *lb, Vertex *v) {
double xa1 = la->v1.x, ya1 = la->v1.y; double xa1 = la->v1.getX(), ya1 = la->v1.getY();
double xa2 = la->v2.x, ya2 = la->v2.y; double xa2 = la->v2.getX(), ya2 = la->v2.getY();
double xb1 = lb->v1.x, yb1 = lb->v1.y; double xb1 = lb->v1.getX(), yb1 = lb->v1.getY();
double xb2 = lb->v2.x, yb2 = lb->v2.y; double xb2 = lb->v2.getX(), yb2 = lb->v2.getY();
double temp; double temp;
int switched = 0; int switched = 0;
VERTEX v2; Vertex v2;
if(v == NULL) v = &v2; if(v == NULL) v = &v2;
@ -201,12 +190,12 @@ int lineIntersection(const LINE *la, const LINE *lb, VERTEX *v) {
return (xa1 == xb1) ? INTERSECTION_IDENTICAL : INTERSECTION_NONE; return (xa1 == xb1) ? INTERSECTION_IDENTICAL : INTERSECTION_NONE;
if(xa1 == xa2) { if(xa1 == xa2) {
v->x = xa1; v->setX(xa1);
v->y = yb1; v->setY(yb1);
} }
else if(xb1 == xb2) { else if(xb1 == xb2) {
v->x = xb1; v->setX(xb1);
v->y = ya1; v->setY(ya1);
} }
else { else {
double ma = (ya2-ya1)/(xa2-xa1); double ma = (ya2-ya1)/(xa2-xa1);
@ -216,12 +205,12 @@ int lineIntersection(const LINE *la, const LINE *lb, VERTEX *v) {
if(ma == mb) return (ba == bb) ? INTERSECTION_IDENTICAL : INTERSECTION_NONE; if(ma == mb) return (ba == bb) ? INTERSECTION_IDENTICAL : INTERSECTION_NONE;
v->x = (bb-ba)/(ma-mb); v->setX((bb-ba)/(ma-mb));
v->y = ma*v->x + ba; v->setY(ma*v->getX() + ba);
} }
if(switched) { if(switched) {
temp = v->x; v->x = v->y; v->y = temp; temp = v->getX(); v->setX(v->getY()); v->setY(temp);
//switch back everything for segment tests //switch back everything for segment tests
temp = xa1; xa1 = ya1; ya1 = temp; temp = xa1; xa1 = ya1; ya1 = temp;
@ -230,25 +219,25 @@ int lineIntersection(const LINE *la, const LINE *lb, VERTEX *v) {
temp = xb2; xb2 = yb2; yb2 = temp; temp = xb2; xb2 = yb2; yb2 = temp;
} }
if(v->x < MIN(xa1,xa2) || v->x > MAX(xa1, xa2) || v->y < MIN(ya1,ya2) || v->y > MAX(ya1, ya2)) { if(v->getX() < MIN(xa1,xa2) || v->getX() > MAX(xa1, xa2) || v->getY() < MIN(ya1,ya2) || v->getY() > MAX(ya1, ya2)) {
if(v->x < MIN(xb1,xb2) || v->x > MAX(xb1, xb2) || v->y < MIN(yb1,yb2) || v->y > MAX(yb1, yb2)) if(v->getX() < MIN(xb1,xb2) || v->getX() > MAX(xb1, xb2) || v->getY() < MIN(yb1,yb2) || v->getY() > MAX(yb1, yb2))
return INTERSECTION_LINE_LINE; return INTERSECTION_LINE_LINE;
else else
return INTERSECTION_LINE_SEGMENT; return INTERSECTION_LINE_SEGMENT;
} }
else if(v->x < MIN(xb1,xb2) || v->x > MAX(xb1, xb2) || v->y < MIN(yb1,yb2) || v->y > MAX(yb1, yb2)) else if(v->getX() < MIN(xb1,xb2) || v->getX() > MAX(xb1, xb2) || v->getY() < MIN(yb1,yb2) || v->getY() > MAX(yb1, yb2))
return INTERSECTION_SEGMENT_LINE; return INTERSECTION_SEGMENT_LINE;
else else
return INTERSECTION_SEGMENT_SEGMENT; return INTERSECTION_SEGMENT_SEGMENT;
} }
int lineRectIntersection(const LINE *l, const RECTANGLE *rect, int edge, VERTEX *v) { int lineRectIntersection(const LINE *l, const RECTANGLE *rect, int edge, Vertex *v) {
const double minX = rect->x, maxX = rect->x+rect->width; const double minX = rect->x, maxX = rect->x+rect->width;
const double minY = rect->y, maxY = rect->y+rect->height; const double minY = rect->y, maxY = rect->y+rect->height;
const LINE top = {{minX, minY}, {maxX, minY}}; const LINE top = {Vertex(minX, minY), Vertex(maxX, minY)};
const LINE bottom = {{minX, maxY}, {maxX, maxY}}; const LINE bottom = {Vertex(minX, maxY), Vertex(maxX, maxY)};
const LINE left = {{minX, minY}, {minX, maxY}}; const LINE left = {Vertex(minX, minY), Vertex(minX, maxY)};
const LINE right = {{maxX, minY}, {maxX, maxY}}; const LINE right = {Vertex(maxX, minY), Vertex(maxX, maxY)};
if((edge & EDGE_TOP) && (lineIntersection(&top, l, v) == INTERSECTION_SEGMENT_SEGMENT)) if((edge & EDGE_TOP) && (lineIntersection(&top, l, v) == INTERSECTION_SEGMENT_SEGMENT))
return EDGE_TOP; return EDGE_TOP;
@ -259,12 +248,12 @@ int lineRectIntersection(const LINE *l, const RECTANGLE *rect, int edge, VERTEX
if((edge & EDGE_RIGHT) && (lineIntersection(&right, l, v) == INTERSECTION_SEGMENT_SEGMENT)) if((edge & EDGE_RIGHT) && (lineIntersection(&right, l, v) == INTERSECTION_SEGMENT_SEGMENT))
return EDGE_RIGHT; return EDGE_RIGHT;
v->x = v->y = 0; v->setLocation(0, 0);
return EDGE_NONE; return EDGE_NONE;
} }
int lineRectIntersections(const LINE *line, const RECTANGLE *rect, int edge, VERTEX *v1, VERTEX *v2) { int lineRectIntersections(const LINE *line, const RECTANGLE *rect, int edge, Vertex *v1, Vertex *v2) {
int ret = EDGE_NONE; int ret = EDGE_NONE;
ret |= lineRectIntersection(line, rect, edge, v1); ret |= lineRectIntersection(line, rect, edge, v1);
@ -289,18 +278,18 @@ gboolean linePolygonIntersection(const LINE *l, const POLYGON *p) {
} }
static void edgeVertex(VERTEX *v, int edge, const RECTANGLE *rect) { static void edgeVertex(Vertex *v, int edge, const RECTANGLE *rect) {
if(edge == EDGE_NONE) if(edge == EDGE_NONE)
edge = vertexInRect(v, rect); edge = vertexInRect(v, rect);
if(edge & EDGE_LEFT) v->x = rect->x; if(edge & EDGE_LEFT) v->setX(rect->x);
else if(edge & EDGE_RIGHT) v->x = rect->x+rect->width; else if(edge & EDGE_RIGHT) v->setX(rect->x+rect->width);
if(edge & EDGE_TOP) v->y = rect->y; if(edge & EDGE_TOP) v->setY(rect->y);
else if(edge & EDGE_BOTTOM) v->y = rect->y+rect->height; else if(edge & EDGE_BOTTOM) v->setY(rect->y+rect->height);
} }
static int simplifyVertex(VERTEX *v, const VERTEX *to, const RECTANGLE *rect) { static int simplifyVertex(Vertex *v, const Vertex *to, const RECTANGLE *rect) {
LINE l = {*v, *to}; LINE l = {*v, *to};
int edge, edge2; int edge, edge2;
@ -317,12 +306,12 @@ static int simplifyVertex(VERTEX *v, const VERTEX *to, const RECTANGLE *rect) {
static void addSimplifiedLine(const VERTEX *v1, const VERTEX *v2, const RECTANGLE *rect, int last, POLYGON *out) { static void addSimplifiedLine(const Vertex *v1, const Vertex *v2, const RECTANGLE *rect, int last, POLYGON *out) {
const LINE d1 = {{rect->x, rect->y}, {rect->x+rect->width, rect->y+rect->height}}; const LINE d1 = {Vertex(rect->x, rect->y), Vertex(rect->x+rect->width, rect->y+rect->height)};
const LINE d2 = {{rect->x, rect->y+rect->height}, {rect->x+rect->width, rect->y}}; const LINE d2 = {Vertex(rect->x, rect->y+rect->height), Vertex(rect->x+rect->width, rect->y)};
LINE l = {*v1, *v2}; LINE l = {*v1, *v2};
VERTEX v, vi; Vertex v, vi;
int edge1, edge2; int edge1, edge2;
@ -349,7 +338,7 @@ static void addSimplifiedLine(const VERTEX *v1, const VERTEX *v2, const RECTANGL
} }
void simplifyPolygon(const POLYGON *in, const RECTANGLE *rect, POLYGON *out) { void simplifyPolygon(const POLYGON *in, const RECTANGLE *rect, POLYGON *out) {
VERTEX v; Vertex v;
int i; int i;
if(in->nVertices == 0) return; if(in->nVertices == 0) return;

View file

@ -2,6 +2,7 @@
#define GEOMETRY_H_ #define GEOMETRY_H_
#include "Vertex.h"
#include <glib.h> #include <glib.h>
#define EDGE_NONE 0 #define EDGE_NONE 0
@ -21,41 +22,34 @@
#define INTERSECTION_SEGMENT_SEGMENT 7 #define INTERSECTION_SEGMENT_SEGMENT 7
typedef struct _VERTEX {
double x, y;
} VERTEX;
typedef struct _RECTANGLE { typedef struct _RECTANGLE {
double x, y, width, height; double x, y, width, height;
} RECTANGLE; } RECTANGLE;
typedef struct _LINE { typedef struct _LINE {
VERTEX v1, v2; Vertex v1, v2;
} LINE; } LINE;
typedef struct _VERTEX_LIST { typedef struct _VERTEX_LIST {
unsigned int nVertices; unsigned int nVertices;
VERTEX *vertices; Vertex *vertices;
} VERTEX_LIST, POLYGON; } VERTEX_LIST, POLYGON;
void addVertex(VERTEX_LIST *list, const VERTEX *v); void addVertex(VERTEX_LIST *list, const Vertex *v);
void insertVertex(VERTEX_LIST *list, const VERTEX *v, unsigned int n); void insertVertex(VERTEX_LIST *list, const Vertex *v, unsigned int n);
void deleteVertex(VERTEX_LIST *list, unsigned int n); void deleteVertex(VERTEX_LIST *list, unsigned int n);
double vertexDistanceSquare(const VERTEX *v1, const VERTEX *v2); int vertexOnLine(const Vertex *v, const LINE *l);
double vertexDistance(const VERTEX *v1, const VERTEX *v2); int vertexInRect(const Vertex *v, const RECTANGLE *rect);
gboolean vertexInPolygon(const Vertex *v, const POLYGON *p);
int vertexOnLine(const VERTEX *v, const LINE *l);
int vertexInRect(const VERTEX *v, const RECTANGLE *rect);
gboolean vertexInPolygon(const VERTEX *v, const POLYGON *p);
double polygonPerimeter(const POLYGON *p); double polygonPerimeter(const POLYGON *p);
double polygonArea(const POLYGON *p); double polygonArea(const POLYGON *p);
int lineIntersection(const LINE *la, const LINE *lb, VERTEX *v); int lineIntersection(const LINE *la, const LINE *lb, Vertex *v);
int lineRectIntersection(const LINE *l, const RECTANGLE *rect, int edge, VERTEX *v); int lineRectIntersection(const LINE *l, const RECTANGLE *rect, int edge, Vertex *v);
int lineRectIntersections(const LINE *line, const RECTANGLE *rect, int edge, VERTEX *v1, VERTEX *v2); int lineRectIntersections(const LINE *line, const RECTANGLE *rect, int edge, Vertex *v1, Vertex *v2);
gboolean linePolygonIntersection(const LINE *l, const POLYGON *p); gboolean linePolygonIntersection(const LINE *l, const POLYGON *p);
void simplifyPolygon(const POLYGON *in, const RECTANGLE *rect, POLYGON *out); void simplifyPolygon(const POLYGON *in, const RECTANGLE *rect, POLYGON *out);

View file

@ -32,7 +32,7 @@ static gboolean scrollEvent(GtkWidget *widget, GdkEventScroll *event, gpointer u
} }
static gboolean buttonEvent(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { static gboolean buttonEvent(GtkWidget *widget, GdkEventButton *event, gpointer user_data) {
VERTEX v = {event->x, event->y}; Vertex v(event->x, event->y);
switch(event->type) { switch(event->type) {
case GDK_BUTTON_PRESS: case GDK_BUTTON_PRESS:
@ -65,14 +65,11 @@ static gboolean buttonEvent(GtkWidget *widget, GdkEventButton *event, gpointer u
} }
gboolean crossingNotifyEvent(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data) { gboolean crossingNotifyEvent(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data) {
VERTEX v; Vertex v(event->x, event->y);
switch(event->type) { switch(event->type) {
case GDK_ENTER_NOTIFY: case GDK_ENTER_NOTIFY:
v.x = event->x;
v.y = event->y;
viewToImage(&v); viewToImage(&v);
setHoveredVertex(&v); setHoveredVertex(&v);
@ -87,11 +84,9 @@ gboolean crossingNotifyEvent(GtkWidget *widget, GdkEventCrossing *event, gpointe
} }
gboolean motionNotifyEvent(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { gboolean motionNotifyEvent(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) {
VERTEX v; Vertex v(event->x, event->y);
ROOM *last = getHoveredRoom(); ROOM *last = getHoveredRoom();
v.x = event->x;
v.y = event->y;
viewToImage(&v); viewToImage(&v);