From 96e9d04527dc17a2a4f8c2f7034c1c356ed5186e Mon Sep 17 00:00:00 2001 From: neoraider Date: Sun, 16 Sep 2007 20:59:04 +0000 Subject: zoomedit: C++ized Line & Rectangle --- Line.cpp | 41 ++++++++++++++++++++--- Line.h | 34 ++++++++++++++++--- Makefile.am | 2 +- Makefile.in | 19 +++++++++-- Polygon.cpp | 24 +++++++------- Polygon.h | 2 +- Rectangle.cpp | 50 ++++++++++++++++++++++++++++ Rectangle.h | 54 ++++++++++++++++++++++++++++++ draw.cpp | 30 ++++++++--------- edit.cpp | 38 ++++++++++----------- geometry.cpp | 105 ++++++++++------------------------------------------------ geometry.h | 27 ++------------- 12 files changed, 253 insertions(+), 173 deletions(-) create mode 100644 Rectangle.cpp create mode 100644 Rectangle.h diff --git a/Line.cpp b/Line.cpp index c755050..4bc0c3c 100644 --- a/Line.cpp +++ b/Line.cpp @@ -2,11 +2,42 @@ #include -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 #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 { 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 + + +#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 -#include -#include -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 +#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_*/ -- cgit v1.2.3