#include "geometry.h" static void edgeVertex(Vertex *v, int edge, const Rectangle *rect) { if(edge == EDGE_NONE) edge = rect->edges(*v); 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->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); int edge, edge2; edge = rect->edges(*v); if(edge == EDGE_NONE) return EDGE_NONE; 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(rect->getVertex1(), rect->getVertex2()); const Line d2(rect->getVertex1().getX(), rect->getVertex2().getY(), rect->getVertex2().getX(), rect->getVertex1().getY()); Line l(*v1, *v2); Vertex v, vi; int edge1, edge2; v = *v1; if((edge1 = simplifyVertex(&v, v2, rect)) != EDGE_NONE) out->push_back(v); v = *v2; edge2 = simplifyVertex(&v, v1, rect); if(edge1 != EDGE_NONE && edge2 != EDGE_NONE && !(edge1 & edge2)) { if(l.intersects(d1, &vi) == INTERSECTION_SEGMENT_LINE) { edgeVertex(&vi, 0, rect); out->push_back(vi); } else if(l.intersects(d1, &vi) == INTERSECTION_SEGMENT_LINE) { edgeVertex(&vi, 0, rect); out->push_back(vi); } } if(!last) out->push_back(v); } void simplifyPolygon(const Polygon *in, const Rectangle *rect, Polygon *out) { Vertex v; if(in->empty()) return; else if(in->size() == 1) { out->push_back(in->front()); return; } v = in->front(); simplifyVertex(&v, &in->back(), rect); out->push_back(v); for(Polygon::const_iterator v2 = in->begin(); v2 != in->end(); v2++) { Polygon::const_iterator v3 = v2+1; if(v3 == in->end()) v3 = in->begin(); addSimplifiedLine(&*v2, &*v3, rect, (v3 == in->begin()), out); } }