summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Line.cpp41
-rw-r--r--Line.h34
-rw-r--r--Makefile.am2
-rw-r--r--Makefile.in19
-rw-r--r--Polygon.cpp24
-rw-r--r--Polygon.h2
-rw-r--r--Rectangle.cpp50
-rw-r--r--Rectangle.h54
-rw-r--r--draw.cpp30
-rw-r--r--edit.cpp38
-rw-r--r--geometry.cpp105
-rw-r--r--geometry.h27
12 files changed, 253 insertions, 173 deletions
diff --git a/Line.cpp b/Line.cpp
index c755050..4bc0c3c 100644
--- a/Line.cpp
+++ b/Line.cpp
@@ -2,11 +2,42 @@
#include <math.h>
-int lineIntersection(const LINE *la, const LINE *lb, Vertex *v) {
- double xa1 = la->v1.getX(), ya1 = la->v1.getY();
- double xa2 = la->v2.getX(), ya2 = la->v2.getY();
- double xb1 = lb->v1.getX(), yb1 = lb->v1.getY();
- double xb2 = lb->v2.getX(), yb2 = lb->v2.getY();
+bool Line::contains(const Vertex &v) const {
+ if(v1.getX() == v2.getX() && v1.getY() == v2.getY()) {
+ if(v1.getX() == v.getX() && v1.getY() == v.getY())
+ return true;
+ else
+ return false;
+ }
+
+ if(v1.getX() == v2.getX()) {
+ if(v1.getX() != v.getX())
+ return false;
+ else if(v.getY() >= fmin(v1.getY(), v2.getY()) && v.getY() <= fmax(v1.getY(), v2.getY()))
+ return true;
+ else
+ return false;
+ }
+
+ if(v1.getY() == v2.getY()) {
+ if(v1.getY() != v.getY())
+ return false;
+ else if(v.getX() >= fmin(v1.getX(), v2.getX()) && v.getX() <= fmax(v1.getX(), v2.getX()))
+ return true;
+ else
+ return false;
+ }
+ if((v.getX()-v1.getX())/(v2.getX()-v1.getX()) - (v.getY()-v1.getY())/(v2.getY()-v1.getY()) == 0)
+ return true;
+ else
+ return false;
+}
+
+int Line::intersects(const Line &l, Vertex *v) const {
+ double xa1 = v1.getX(), ya1 = v1.getY();
+ double xa2 = v2.getX(), ya2 = v2.getY();
+ double xb1 = l.v1.getX(), yb1 = l.v1.getY();
+ double xb2 = l.v2.getX(), yb2 = l.v2.getY();
double temp;
int switched = 0;
Vertex v2;
diff --git a/Line.h b/Line.h
index 0fad7f3..18f714c 100644
--- a/Line.h
+++ b/Line.h
@@ -2,6 +2,7 @@
#define LINE_H_
#include "Vertex.h"
+#include <math.h>
#define INTERSECTION_ERROR -1
@@ -13,11 +14,34 @@
#define INTERSECTION_SEGMENT_LINE 6
#define INTERSECTION_SEGMENT_SEGMENT 7
-typedef struct _LINE {
- Vertex v1, v2;
-} LINE;
+class Line {
+ private:
+ Vertex v1, v2;
+ public:
+ Line() {}
+ Line(const Vertex& v1, const Vertex& v2) {
+ this->v1 = v1; this->v2 = v2;
+ }
+ Line(double x1, double y1, double x2, double y2) {
+ v1.setLocation(x1, y1);
+ v2.setLocation(x2, y2);
+ }
+
+ Vertex &getVertex1() {return v1;}
+ const Vertex &getVertex1() const {return v1;}
+ void setVertex1(const Vertex &v) {v1 = v;}
+
+ Vertex &getVertex2() {return v2;}
+ const Vertex &getVertex2() const {return v2;}
+ void setVertex2(const Vertex &v) {v2 = v;}
+
+ double lengthSq() const {return v1.distanceSq(v2);}
+ double length() const {return sqrt(lengthSq());}
+
+ bool contains(const Vertex &v) const;
+
+ int intersects(const Line &l, Vertex *v) const;
+};
-int lineIntersection(const LINE *la, const LINE *lb, Vertex *v);
-
#endif /*LINE_H_*/
diff --git a/Makefile.am b/Makefile.am
index b327e10..243629a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
bin_PROGRAMS = zoomedit
-zoomedit_SOURCES = zoomedit.cpp window.cpp ui.cpp draw.cpp level.cpp geometry.cpp edit.cpp Vertex.cpp Line.cpp Polygon.cpp
+zoomedit_SOURCES = zoomedit.cpp window.cpp ui.cpp draw.cpp level.cpp geometry.cpp edit.cpp Vertex.cpp Line.cpp Polygon.cpp Rectangle.cpp
zoomedit_CPPFLAGS = @GTK_CFLAGS@
zoomedit_LDADD = @GTK_LIBS@ \ No newline at end of file
diff --git a/Makefile.in b/Makefile.in
index d6e0969..8230eb9 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -53,7 +53,7 @@ am_zoomedit_OBJECTS = zoomedit-zoomedit.$(OBJEXT) \
zoomedit-draw.$(OBJEXT) zoomedit-level.$(OBJEXT) \
zoomedit-geometry.$(OBJEXT) zoomedit-edit.$(OBJEXT) \
zoomedit-Vertex.$(OBJEXT) zoomedit-Line.$(OBJEXT) \
- zoomedit-Polygon.$(OBJEXT)
+ zoomedit-Polygon.$(OBJEXT) zoomedit-Rectangle.$(OBJEXT)
zoomedit_OBJECTS = $(am_zoomedit_OBJECTS)
zoomedit_DEPENDENCIES =
DEFAULT_INCLUDES = -I.@am__isrc@
@@ -171,7 +171,7 @@ sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-zoomedit_SOURCES = zoomedit.cpp window.cpp ui.cpp draw.cpp level.cpp geometry.cpp edit.cpp Vertex.cpp Line.cpp Polygon.cpp
+zoomedit_SOURCES = zoomedit.cpp window.cpp ui.cpp draw.cpp level.cpp geometry.cpp edit.cpp Vertex.cpp Line.cpp Polygon.cpp Rectangle.cpp
zoomedit_CPPFLAGS = @GTK_CFLAGS@
zoomedit_LDADD = @GTK_LIBS@
all: config.h
@@ -264,6 +264,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-Line.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-Polygon.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoomedit-Rectangle.Po@am__quote@
@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-edit.Po@am__quote@
@@ -427,6 +428,20 @@ zoomedit-Polygon.obj: Polygon.cpp
@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-Polygon.obj `if test -f 'Polygon.cpp'; then $(CYGPATH_W) 'Polygon.cpp'; else $(CYGPATH_W) '$(srcdir)/Polygon.cpp'; fi`
+zoomedit-Rectangle.o: Rectangle.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zoomedit-Rectangle.o -MD -MP -MF $(DEPDIR)/zoomedit-Rectangle.Tpo -c -o zoomedit-Rectangle.o `test -f 'Rectangle.cpp' || echo '$(srcdir)/'`Rectangle.cpp
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/zoomedit-Rectangle.Tpo $(DEPDIR)/zoomedit-Rectangle.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Rectangle.cpp' object='zoomedit-Rectangle.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-Rectangle.o `test -f 'Rectangle.cpp' || echo '$(srcdir)/'`Rectangle.cpp
+
+zoomedit-Rectangle.obj: Rectangle.cpp
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(zoomedit_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT zoomedit-Rectangle.obj -MD -MP -MF $(DEPDIR)/zoomedit-Rectangle.Tpo -c -o zoomedit-Rectangle.obj `if test -f 'Rectangle.cpp'; then $(CYGPATH_W) 'Rectangle.cpp'; else $(CYGPATH_W) '$(srcdir)/Rectangle.cpp'; fi`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/zoomedit-Rectangle.Tpo $(DEPDIR)/zoomedit-Rectangle.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='Rectangle.cpp' object='zoomedit-Rectangle.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-Rectangle.obj `if test -f 'Rectangle.cpp'; then $(CYGPATH_W) 'Rectangle.cpp'; else $(CYGPATH_W) '$(srcdir)/Rectangle.cpp'; fi`
+
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
diff --git a/Polygon.cpp b/Polygon.cpp
index 05d06ca..9340135 100644
--- a/Polygon.cpp
+++ b/Polygon.cpp
@@ -38,11 +38,11 @@ int Polygon::quadrant(const Vertex &v) const {
}
bool Polygon::contains(const Vertex &v) const {
+ const Line d1(-1, -1, 1, 1);
+ const Line d2(-1, 1, 1, -1);
int d = 0;
int q, ql, q2;
- LINE d1 = {Vertex(-1, -1), Vertex(1, 1)};
- LINE d2 = {Vertex(-1, 1), Vertex(1, -1)};
- LINE l;
+ Line l;
Vertex v2;
@@ -73,11 +73,11 @@ bool Polygon::contains(const Vertex &v) const {
d--;
break;
default:
- l.v1 = ((it == begin()) ? back() : *(it-1)) - v;
- l.v2 = v2;
+ l.setVertex1(((it == begin()) ? back() : *(it-1)) - v);
+ l.setVertex2(v2);
if(q == 1 || q == 3) {
- if(!(lineIntersection(&l, &d2, &v2) & INTERSECTION_LINE)) return false;
+ if(!(l.intersects(d2, &v2) & INTERSECTION_LINE)) return false;
q2 = quadrant(v2);
if(q2 == 0) return true;
@@ -86,7 +86,7 @@ bool Polygon::contains(const Vertex &v) const {
else d += 2;
}
else {
- if(!(lineIntersection(&l, &d1, &v2) & INTERSECTION_LINE)) return false;
+ if(!(l.intersects(d1, &v2) & INTERSECTION_LINE)) return false;
q2 = quadrant(v2);
if(q2 == 0) return true;
@@ -100,17 +100,17 @@ bool Polygon::contains(const Vertex &v) const {
return (d != 0);
}
-bool Polygon::intersects(const LINE *l) const {
- LINE line;
+bool Polygon::intersects(const Line &l) const {
+ Line line;
for(Polygon::const_iterator it = begin(); it != end(); it++) {
Polygon::const_iterator it2 = it+1;
if(it2 == end()) it2 = begin();
- line.v1 = *it;
- line.v2 = *it2;
+ line.setVertex1(*it);
+ line.setVertex2(*it2);
- if(lineIntersection(l, &line, NULL) == INTERSECTION_SEGMENT_SEGMENT)
+ if(l.intersects(line, NULL) == INTERSECTION_SEGMENT_SEGMENT)
return true;
}
diff --git a/Polygon.h b/Polygon.h
index 2a79a94..093a160 100644
--- a/Polygon.h
+++ b/Polygon.h
@@ -13,7 +13,7 @@ class Polygon : public std::vector<Vertex> {
double perimeter() const;
bool contains(const Vertex &v) const;
- bool intersects(const LINE *l) const;
+ bool intersects(const Line &l) const;
};
#endif /*POLYGON_H_*/
diff --git a/Rectangle.cpp b/Rectangle.cpp
new file mode 100644
index 0000000..c90ab0d
--- /dev/null
+++ b/Rectangle.cpp
@@ -0,0 +1,50 @@
+#include "Rectangle.h"
+
+bool Rectangle::contains(const Vertex &v) const {
+ return (edges(v) == EDGE_NONE);
+}
+
+int Rectangle::edges(const Vertex &v) const {
+ int ret = EDGE_NONE;
+
+ if(v.getX() < v1.getX()) ret |= EDGE_LEFT;
+ else if(v.getX() >= v2.getX()) ret |= EDGE_RIGHT;
+
+ if(v.getY() < v1.getY()) ret |= EDGE_TOP;
+ else if(v.getY() >= v2.getY()) ret |= EDGE_BOTTOM;
+
+ return ret;
+}
+
+int Rectangle::intersects(const Line &l, Vertex *v, int edge) const {
+ const Line top(v1.getX(), v1.getY(), v2.getX(), v1.getY());
+ const Line bottom(v1.getX(), v2.getY(), v2.getX(), v2.getY());
+ const Line left(v1.getX(), v1.getY(), v1.getX(), v2.getY());
+ const Line right(v2.getX(), v1.getY(), v2.getX(), v2.getY());
+
+ if(edge == EDGE_NONE) edge = edges(l.getVertex1());
+
+ if((edge & EDGE_TOP) && (top.intersects(l, v) == INTERSECTION_SEGMENT_SEGMENT))
+ return EDGE_TOP;
+ if((edge & EDGE_BOTTOM) && (bottom.intersects(l, v) == INTERSECTION_SEGMENT_SEGMENT))
+ return EDGE_BOTTOM;
+ if((edge & EDGE_LEFT) && (left.intersects(l, v) == INTERSECTION_SEGMENT_SEGMENT))
+ return EDGE_LEFT;
+ if((edge & EDGE_RIGHT) && (right.intersects(l, v) == INTERSECTION_SEGMENT_SEGMENT))
+ return EDGE_RIGHT;
+
+ v->setLocation(0, 0);
+
+ return EDGE_NONE;
+}
+
+int Rectangle::intersects(const Line &l, Vertex *v1, Vertex *v2, int edge) const {
+ int ret = EDGE_NONE;
+
+ if(edge == EDGE_NONE) edge = edges(l.getVertex1());
+
+ ret |= intersects(l, v1, edge);
+ ret |= intersects(l, v2, EDGE_ALL^edge);
+
+ return ret;
+}
diff --git a/Rectangle.h b/Rectangle.h
new file mode 100644
index 0000000..8a61321
--- /dev/null
+++ b/Rectangle.h
@@ -0,0 +1,54 @@
+#ifndef RECTANGLE_H_
+#define RECTANGLE_H_
+
+#include "Vertex.h"
+#include "Line.h"
+#include <math.h>
+
+
+#define EDGE_NONE 0
+#define EDGE_LEFT (1<<0)
+#define EDGE_RIGHT (1<<1)
+#define EDGE_TOP (1<<2)
+#define EDGE_BOTTOM (1<<3)
+#define EDGE_ALL (EDGE_LEFT|EDGE_RIGHT|EDGE_TOP|EDGE_BOTTOM)
+
+class Rectangle {
+ private:
+ Vertex v1, v2;
+ public:
+ Rectangle() {}
+ Rectangle(const Vertex& v1, const Vertex& v2) {
+ this->v1 = v1; this->v2 = v2;
+ }
+ Rectangle(double x, double y, double width, double height) {
+ v1.setLocation(x, y);
+ v2.setLocation(x+width, y+height);
+ }
+
+ Vertex &getVertex1() {return v1;}
+ const Vertex &getVertex1() const {return v1;}
+ void setVertex1(const Vertex &v) {v1 = v;}
+
+ Vertex &getVertex2() {return v2;}
+ const Vertex &getVertex2() const {return v2;}
+ void setVertex2(const Vertex &v) {v2 = v;}
+
+ double getWidth() const {return v2.getX()-v1.getX();}
+ void setWidth(double width) {v2.setX(v1.getX()+width);}
+
+ double getHeight() const {return v2.getY()-v1.getY();}
+ void setHeight(double height) {v2.setY(v1.getY()+height);}
+
+ double area() const {return getWidth()*getHeight();}
+
+ bool contains(const Vertex &v) const;
+
+ int edges(const Vertex &v) const;
+
+ int intersects(const Line &l, Vertex *v, int edge = EDGE_NONE) const;
+ int intersects(const Line &l, Vertex *v1, Vertex *v2, int edge = EDGE_NONE) const;
+};
+
+
+#endif /*RECTANGLE_H_*/
diff --git a/draw.cpp b/draw.cpp
index 65cf13a..edb0657 100644
--- a/draw.cpp
+++ b/draw.cpp
@@ -13,13 +13,15 @@ static double xTranslate = 0.0, yTranslate = 0.0;
static gboolean repaint = FALSE;
-static void drawGrid(cairo_t *cr, const RECTANGLE *rect) {
+static void drawGrid(cairo_t *cr, const Rectangle *rect) {
double depth = log10(scale)-0.75;
double depth2 = floor(depth);
double step = pow(0.1, depth2);
double d;
int i;
gchar *string;
+ double x1 = rect->getVertex1().getX(), y1 = rect->getVertex1().getY();
+ double x2 = rect->getVertex2().getX(), y2 = rect->getVertex2().getY();
cairo_set_font_size(cr, 10.0/scale);
@@ -28,9 +30,9 @@ static void drawGrid(cairo_t *cr, const RECTANGLE *rect) {
d = MIN(0.4*(depth-depth2+i), 0.5);
cairo_set_source_rgb(cr, d, d, d);
- for(d = rect->x - fmod(rect->x, step) - step; d <= rect->x+rect->width; d+=step) {
- cairo_move_to(cr, d, rect->y);
- cairo_line_to(cr, d, rect->y+rect->height);
+ for(d = x1 - fmod(x1, step) - step; d <= x2; d+=step) {
+ cairo_move_to(cr, d, y1);
+ cairo_line_to(cr, d, y2);
if(step > 0.005) {
if(step > 0.5)
@@ -38,16 +40,16 @@ static void drawGrid(cairo_t *cr, const RECTANGLE *rect) {
else
string = g_strdup_printf("%.*f", -(int)floor(log10(step*1.1)), d+step/10);
- cairo_move_to(cr, d+1/scale, rect->y+11/scale);
+ cairo_move_to(cr, d+1/scale, y1+11/scale);
cairo_show_text(cr, string);
g_free(string);
}
}
- for(d = rect->y - fmod(rect->y, step) - step; d <= rect->y+rect->height; d+=step) {
- cairo_move_to(cr, rect->x, d);
- cairo_line_to(cr, rect->x+rect->width, d);
+ for(d = y1 - fmod(y1, step) - step; d <= y2; d+=step) {
+ cairo_move_to(cr, x1, d);
+ cairo_line_to(cr, x2, d);
if(step > 0.005) {
if(step > 0.5)
@@ -55,7 +57,7 @@ static void drawGrid(cairo_t *cr, const RECTANGLE *rect) {
else
string = g_strdup_printf("%.*f", -(int)floor(log10(step*1.1)), d+step/10);
- cairo_move_to(cr, rect->x+3/scale, d+11/scale);
+ cairo_move_to(cr, x1+3/scale, d+11/scale);
cairo_show_text(cr, string);
g_free(string);
@@ -68,7 +70,7 @@ static void drawGrid(cairo_t *cr, const RECTANGLE *rect) {
}
}
-static void polygon2path(cairo_t *cr, const Polygon *polygon, const RECTANGLE *rect, gboolean close) {
+static void polygon2path(cairo_t *cr, const Polygon *polygon, const Rectangle *rect, gboolean close) {
Polygon polygon2;
// no vertices
@@ -94,7 +96,7 @@ static void polygon2path(cairo_t *cr, const Polygon *polygon, const RECTANGLE *r
gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
cairo_t *cr;
Vertex v1(-1, -1), v2(widget->allocation.width+1, widget->allocation.height+1);
- RECTANGLE rect;
+ Rectangle rect;
gboolean vertexOk;
static GdkPixmap *pixmap = NULL;
static double lastImageWidth = 0.0, lastImageHeight = 0.0;
@@ -108,10 +110,8 @@ gboolean drawTopView(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
viewToImage(&v1);
viewToImage(&v2);
- rect.x = v1.getX();
- rect.y = v1.getY();
- rect.width = v2.getX()-v1.getX();
- rect.height = v2.getY()-v1.getY();
+ rect.setVertex1(v1);
+ rect.setVertex2(v2);
if(pixmap == NULL || fabs(lastImageWidth - getImageWidth()) >= 0.000001 || fabs(lastImageHeight - getImageHeight()) >= 0.000001 ||
lastWidth != widget->allocation.width || lastHeight != widget->allocation.height || lastEditMode != getEditMode() || repaint)
diff --git a/edit.cpp b/edit.cpp
index e03f92c..96dce6e 100644
--- a/edit.cpp
+++ b/edit.cpp
@@ -75,28 +75,28 @@ ROOM *getHoveredRoom() {
return hoveredRoom;
}
-static bool isLineOk(LINE *l) {
+static bool isLineOk(Line *l) {
LEVEL *lvl = getLevel();
- LINE l2;
+ Line l2;
if(activeRoom) {
for(int i = 0; i+2 < activeRoom->polygon.size(); i++) {
- l2.v1 = activeRoom->polygon[i];
- l2.v2 = activeRoom->polygon[i+1];
+ l2.setVertex1(activeRoom->polygon[i]);
+ l2.setVertex2(activeRoom->polygon[i+1]);
- if(lineIntersection(l, &l2, NULL) == INTERSECTION_SEGMENT_SEGMENT) return false;
+ if(l->intersects(l2, NULL) == INTERSECTION_SEGMENT_SEGMENT) return false;
}
if(activeRoom->polygon.size() > 1) {
- l2.v1 = activeRoom->polygon[activeRoom->polygon.size()-2];
- l2.v2 = activeRoom->polygon.back();
- if(vertexOnLine(&l->v2, &l2)) return false;
+ l2.setVertex1(activeRoom->polygon[activeRoom->polygon.size()-2]);
+ l2.setVertex2(activeRoom->polygon.back());
+ if(l2.contains(l->getVertex2())) return false;
}
}
for(int i = 0; i < lvl->nRooms; i++) {
- if(lvl->rooms[i].polygon.intersects(l))
+ if(lvl->rooms[i].polygon.intersects(*l))
return false;
}
@@ -105,7 +105,7 @@ static bool isLineOk(LINE *l) {
bool isVertexOk(Vertex *v) {
LEVEL *lvl = getLevel();
- LINE l;
+ Line l;
int i;
@@ -116,8 +116,8 @@ bool isVertexOk(Vertex *v) {
if(!(getActiveRoom() && !getActiveRoom()->polygon.empty()))
return true;
- l.v1 = getActiveRoom()->polygon.back();
- l.v2 = *v;
+ l.setVertex1(getActiveRoom()->polygon.back());
+ l.setVertex2(*v);
return isLineOk(&l);
}
@@ -126,7 +126,7 @@ bool isVertexOk(Vertex *v) {
bool isPolygonOk(Polygon *polygon) {
LEVEL *lvl = getLevel();
- LINE l, l2;
+ Line l, l2;
if(polygon->empty()) return false;
@@ -147,11 +147,11 @@ bool isPolygonOk(Polygon *polygon) {
Polygon::const_iterator it2 = it+1;
if(it2 == polygon->end()) it2 = polygon->begin();
- l.v1 = *it;
- l.v2 = *it2;
+ l.setVertex1(*it);
+ l.setVertex2(*it2);
for(int i = 0; i < lvl->nRooms; i++) {
- if(lvl->rooms[i].polygon.intersects(&l))
+ if(lvl->rooms[i].polygon.intersects(l))
return false;
}
@@ -162,10 +162,10 @@ bool isPolygonOk(Polygon *polygon) {
if(it == polygon->begin() && it4 == polygon->begin()) continue;
- l2.v1 = *it3;
- l2.v2 = *it4;
+ l2.setVertex1(*it3);
+ l2.setVertex2(*it4);
- if(lineIntersection(&l, &l2, NULL) == INTERSECTION_SEGMENT_SEGMENT)
+ if(l.intersects(l2, NULL) == INTERSECTION_SEGMENT_SEGMENT)
return false;
}
}
diff --git a/geometry.cpp b/geometry.cpp
index e3adb6b..7f6bb6c 100644
--- a/geometry.cpp
+++ b/geometry.cpp
@@ -1,108 +1,37 @@
#include "geometry.h"
-#include <math.h>
-#include <stdlib.h>
-#include <gtk/gtk.h>
-int vertexOnLine(const Vertex *v, const LINE *l) {
- 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;
- else return 0;
- }
-
- if(l->v1.getX() == l->v2.getX()) {
- if(l->v1.getX() != v->getX()) return 0;
- 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;
- }
-
- if(l->v1.getY() == l->v2.getY()) {
- if(l->v1.getY() != v->getY()) return 0;
- 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;
- }
- 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;
-}
-
-int vertexInRect(const Vertex *v, const RECTANGLE *rect) {
- int ret = EDGE_NONE;
-
- if(v->getX() < rect->x) ret |= EDGE_LEFT;
- else if(v->getX() >= rect->x+rect->width) ret |= EDGE_RIGHT;
-
- if(v->getY() < rect->y) ret |= EDGE_TOP;
- else if(v->getY() >= rect->y+rect->height) ret |= EDGE_BOTTOM;
-
- return ret;
-}
-
-
-int lineRectIntersection(const LINE *l, const RECTANGLE *rect, int edge, Vertex *v) {
- const double minX = rect->x, maxX = rect->x+rect->width;
- const double minY = rect->y, maxY = rect->y+rect->height;
- const LINE top = {Vertex(minX, minY), Vertex(maxX, minY)};
- const LINE bottom = {Vertex(minX, maxY), Vertex(maxX, maxY)};
- const LINE left = {Vertex(minX, minY), Vertex(minX, maxY)};
- const LINE right = {Vertex(maxX, minY), Vertex(maxX, maxY)};
-
- if((edge & EDGE_TOP) && (lineIntersection(&top, l, v) == INTERSECTION_SEGMENT_SEGMENT))
- return EDGE_TOP;
- if((edge & EDGE_BOTTOM) && (lineIntersection(&bottom, l, v) == INTERSECTION_SEGMENT_SEGMENT))
- return EDGE_BOTTOM;
- if((edge & EDGE_LEFT) && (lineIntersection(&left, l, v) == INTERSECTION_SEGMENT_SEGMENT))
- return EDGE_LEFT;
- if((edge & EDGE_RIGHT) && (lineIntersection(&right, l, v) == INTERSECTION_SEGMENT_SEGMENT))
- return EDGE_RIGHT;
-
- v->setLocation(0, 0);
-
- return EDGE_NONE;
-}
-
-int lineRectIntersections(const LINE *line, const RECTANGLE *rect, int edge, Vertex *v1, Vertex *v2) {
- int ret = EDGE_NONE;
-
- ret |= lineRectIntersection(line, rect, edge, v1);
- ret |= lineRectIntersection(line, rect, EDGE_ALL^edge, v2);
-
- return ret;
-}
-
-
-static void edgeVertex(Vertex *v, int edge, const RECTANGLE *rect) {
+static void edgeVertex(Vertex *v, int edge, const Rectangle *rect) {
if(edge == EDGE_NONE)
- edge = vertexInRect(v, rect);
+ edge = rect->edges(*v);
- if(edge & EDGE_LEFT) v->setX(rect->x);
- else if(edge & EDGE_RIGHT) v->setX(rect->x+rect->width);
+ if(edge & EDGE_LEFT) v->setX(rect->getVertex1().getX());
+ else if(edge & EDGE_RIGHT) v->setX(rect->getVertex2().getX());
- if(edge & EDGE_TOP) v->setY(rect->y);
- else if(edge & EDGE_BOTTOM) v->setY(rect->y+rect->height);
+ if(edge & EDGE_TOP) v->setY(rect->getVertex1().getY());
+ else if(edge & EDGE_BOTTOM) v->setY(rect->getVertex2().getY());
}
-static int simplifyVertex(Vertex *v, const Vertex *to, const RECTANGLE *rect) {
- LINE l = {*v, *to};
+static int simplifyVertex(Vertex *v, const Vertex *to, const Rectangle *rect) {
+ Line l(*v, *to);
int edge, edge2;
- edge = vertexInRect(v, rect);
+ edge = rect->edges(*v);
if(edge == EDGE_NONE) return EDGE_NONE;
- edge2 = lineRectIntersection(&l, rect, edge, v);
+ edge2 = rect->intersects(l, v, edge);
if(edge2 != EDGE_NONE) return edge2;
edgeVertex(v, edge, rect);
return edge;
}
-
-
-static void addSimplifiedLine(const Vertex *v1, const Vertex *v2, const RECTANGLE *rect, int last, Polygon *out) {
- const LINE d1 = {Vertex(rect->x, rect->y), Vertex(rect->x+rect->width, rect->y+rect->height)};
- const LINE d2 = {Vertex(rect->x, rect->y+rect->height), Vertex(rect->x+rect->width, rect->y)};
+static void addSimplifiedLine(const Vertex *v1, const Vertex *v2, const Rectangle *rect, int last, Polygon *out) {
+ const Line d1(rect->getVertex1(), rect->getVertex2());
+ const Line d2(rect->getVertex1().getX(), rect->getVertex2().getY(), rect->getVertex2().getX(), rect->getVertex1().getY());
- LINE l = {*v1, *v2};
+ Line l(*v1, *v2);
Vertex v, vi;
int edge1, edge2;
@@ -115,11 +44,11 @@ static void addSimplifiedLine(const Vertex *v1, const Vertex *v2, const RECTANGL
edge2 = simplifyVertex(&v, v1, rect);
if(edge1 != EDGE_NONE && edge2 != EDGE_NONE && !(edge1 & edge2)) {
- if(lineIntersection(&l, &d1, &vi) == INTERSECTION_SEGMENT_LINE) {
+ if(l.intersects(d1, &vi) == INTERSECTION_SEGMENT_LINE) {
edgeVertex(&vi, 0, rect);
out->push_back(vi);
}
- else if(lineIntersection(&l, &d2, &vi) == INTERSECTION_SEGMENT_LINE) {
+ else if(l.intersects(d1, &vi) == INTERSECTION_SEGMENT_LINE) {
edgeVertex(&vi, 0, rect);
out->push_back(vi);
}
@@ -129,7 +58,7 @@ static void addSimplifiedLine(const Vertex *v1, const Vertex *v2, const RECTANGL
out->push_back(v);
}
-void simplifyPolygon(const Polygon *in, const RECTANGLE *rect, Polygon *out) {
+void simplifyPolygon(const Polygon *in, const Rectangle *rect, Polygon *out) {
Vertex v;
if(in->empty()) return;
diff --git a/geometry.h b/geometry.h
index cefd9a3..633a5b4 100644
--- a/geometry.h
+++ b/geometry.h
@@ -2,33 +2,10 @@
#define GEOMETRY_H_
-#include "Vertex.h"
#include "Polygon.h"
-#include "Line.h"
-#include <glib.h>
+#include "Rectangle.h"
-#define EDGE_NONE 0
-#define EDGE_LEFT (1<<0)
-#define EDGE_RIGHT (1<<1)
-#define EDGE_TOP (1<<2)
-#define EDGE_BOTTOM (1<<3)
-#define EDGE_ALL (EDGE_LEFT|EDGE_RIGHT|EDGE_TOP|EDGE_BOTTOM)
-
-
-
-typedef struct _RECTANGLE {
- double x, y, width, height;
-} RECTANGLE;
-
-
-int vertexOnLine(const Vertex *v, const LINE *l);
-int vertexInRect(const Vertex *v, const RECTANGLE *rect);
-
-
-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);
-//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);
#endif /*GEOMETRY_H_*/