From fe87e22b16017b063a8ff2306d8ef0d325de4c29 Mon Sep 17 00:00:00 2001 From: Robert Date: Sat, 17 Apr 2021 03:15:07 +0200 Subject: [PATCH] =?UTF-8?q?=E3=83=97=E3=83=AD=E3=82=B0=E3=83=AC=E3=82=B9?= =?UTF-8?q?=E3=80=82=E3=80=82=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/multipolygon.hpp | 15 +- lib/osmparser/include/osmimember.hpp | 2 +- lib/osmparser/include/osmnode.hpp | 2 +- lib/osmparser/include/osmobject.hpp | 12 +- lib/osmparser/include/util.hpp | 6 +- lib/osmparser/src/osmimember.cpp | 6 +- lib/osmparser/src/osmobject.cpp | 18 +- lib/osmparser/src/osmrelation.cpp | 2 +- lib/osmparser/src/osmway.cpp | 2 +- lib/osmparser/src/util.cpp | 13 +- lib/triangle/CMakeLists.txt | 2 + lib/triangle/src/triangle.c | 274 +++++++++++++-------------- src/main.cpp | 4 + src/multipolygon.cpp | 92 ++++++++- 14 files changed, 271 insertions(+), 179 deletions(-) diff --git a/include/multipolygon.hpp b/include/multipolygon.hpp index c977821..6437d74 100644 --- a/include/multipolygon.hpp +++ b/include/multipolygon.hpp @@ -4,11 +4,24 @@ #include +struct SDL_FPoint; +struct SDL_Renderer; + class Multipolygon { public: Multipolygon(const std::shared_ptr& relation, int width, int height, osmp::Bounds bounds); + void Draw(SDL_Renderer* renderer, int r, int g, int b); + private: - + struct Vertex { + double x, y; + }; + struct Polygon { + std::vector vertices; + std::vector indices; + }; + + std::vector polygons; }; \ No newline at end of file diff --git a/lib/osmparser/include/osmimember.hpp b/lib/osmparser/include/osmimember.hpp index 786d055..b426f72 100644 --- a/lib/osmparser/include/osmimember.hpp +++ b/lib/osmparser/include/osmimember.hpp @@ -40,7 +40,7 @@ namespace osmp // std::map tags; public: - unsigned int id; + uint64_t id; std::string user; unsigned int uid; bool visible; diff --git a/lib/osmparser/include/osmnode.hpp b/lib/osmparser/include/osmnode.hpp index c9e8f94..76d7627 100644 --- a/lib/osmparser/include/osmnode.hpp +++ b/lib/osmparser/include/osmnode.hpp @@ -15,6 +15,6 @@ namespace osmp Node(const tinyxml2::XMLElement* xml, Object* parent); public: - float lat, lon; + double lat, lon; }; } \ No newline at end of file diff --git a/lib/osmparser/include/osmobject.hpp b/lib/osmparser/include/osmobject.hpp index 315d3e6..9870fcd 100644 --- a/lib/osmparser/include/osmobject.hpp +++ b/lib/osmparser/include/osmobject.hpp @@ -20,15 +20,15 @@ namespace osmp std::vector> GetNodes() const; size_t GetNodesSize() const; - std::shared_ptr GetNode(unsigned int id) const; + std::shared_ptr GetNode(uint64_t id) const; std::vector> GetWays() const; size_t GetWaysSize() const; - std::shared_ptr GetWay(unsigned int id) const; + std::shared_ptr GetWay(uint64_t id) const; std::vector> GetRelations() const; size_t GetRelationsSize() const; - std::shared_ptr GetRelation(unsigned int id) const; + std::shared_ptr GetRelation(uint64_t id) const; public: const std::string version; @@ -37,8 +37,8 @@ namespace osmp Bounds bounds; private: - std::map> nodes; - std::map> ways; - std::map> relations; + std::map> nodes; + std::map> ways; + std::map> relations; }; } \ No newline at end of file diff --git a/lib/osmparser/include/util.hpp b/lib/osmparser/include/util.hpp index f1a4f1b..403d8e4 100644 --- a/lib/osmparser/include/util.hpp +++ b/lib/osmparser/include/util.hpp @@ -11,11 +11,11 @@ namespace osmp { typedef struct sBounds { - float minlat, minlon, maxlat, maxlon; + double minlat, minlon, maxlat, maxlon; } Bounds; std::string GetSafeAttributeString(const tinyxml2::XMLElement* elem, const std::string& name); - float GetSafeAttributeFloat(const tinyxml2::XMLElement* elem, const std::string& name); - unsigned int GetSafeAttributeUint(const tinyxml2::XMLElement* elem, const std::string& name); + double GetSafeAttributeFloat(const tinyxml2::XMLElement* elem, const std::string& name); + uint64_t GetSafeAttributeUint64(const tinyxml2::XMLElement* elem, const std::string& name); bool GetSafeAttributeBool(const tinyxml2::XMLElement* elem, const std::string& name); } \ No newline at end of file diff --git a/lib/osmparser/src/osmimember.cpp b/lib/osmparser/src/osmimember.cpp index 31073de..e038607 100644 --- a/lib/osmparser/src/osmimember.cpp +++ b/lib/osmparser/src/osmimember.cpp @@ -11,12 +11,12 @@ namespace osmp type(type), parent(parent) { // Get Attribute - id = GetSafeAttributeUint(element, "id"); + id = GetSafeAttributeUint64(element, "id"); user = GetSafeAttributeString(element, "user"); - uid = GetSafeAttributeUint(element, "uid"); + uid = GetSafeAttributeUint64(element, "uid"); visible = GetSafeAttributeBool(element, "visible"); version = GetSafeAttributeString(element, "version"); - changeset = GetSafeAttributeUint(element, "changeset"); + changeset = GetSafeAttributeUint64(element, "changeset"); timestamp = GetSafeAttributeString(element, "timestamp"); const xml::XMLElement* tag_element = element->FirstChildElement("tag"); diff --git a/lib/osmparser/src/osmobject.cpp b/lib/osmparser/src/osmobject.cpp index 455f9a3..fca53bb 100644 --- a/lib/osmparser/src/osmobject.cpp +++ b/lib/osmparser/src/osmobject.cpp @@ -74,7 +74,7 @@ namespace osmp std::vector> Object::GetNodes() const { std::vector> vecNodes; - for (std::map>::const_iterator it = nodes.begin(); it != nodes.end(); it++) + for (std::map>::const_iterator it = nodes.begin(); it != nodes.end(); it++) vecNodes.push_back(it->second); return vecNodes; @@ -85,9 +85,9 @@ namespace osmp return nodes.size(); } - std::shared_ptr Object::GetNode(unsigned int id) const + std::shared_ptr Object::GetNode(uint64_t id) const { - std::map>::const_iterator node = nodes.find(id); + std::map>::const_iterator node = nodes.find(id); if (node != nodes.end()) return node->second; @@ -97,7 +97,7 @@ namespace osmp std::vector> Object::GetWays() const { std::vector> vecWays; - for (std::map>::const_iterator it = ways.begin(); it != ways.end(); it++) + for (std::map>::const_iterator it = ways.begin(); it != ways.end(); it++) vecWays.push_back(it->second); return vecWays; @@ -108,9 +108,9 @@ namespace osmp return ways.size(); } - std::shared_ptr Object::GetWay(unsigned int id) const + std::shared_ptr Object::GetWay(uint64_t id) const { - std::map>::const_iterator way = ways.find(id); + std::map>::const_iterator way = ways.find(id); if (way != ways.end()) return way->second; @@ -120,7 +120,7 @@ namespace osmp std::vector> Object::GetRelations() const { std::vector> vecRelations; - for (std::map>::const_iterator it = relations.begin(); it != relations.end(); it++) + for (std::map>::const_iterator it = relations.begin(); it != relations.end(); it++) vecRelations.push_back(it->second); return vecRelations; @@ -131,9 +131,9 @@ namespace osmp return relations.size(); } - std::shared_ptr Object::GetRelation(unsigned int id) const + std::shared_ptr Object::GetRelation(uint64_t id) const { - std::map>::const_iterator relation = relations.find(id); + std::map>::const_iterator relation = relations.find(id); if (relation != relations.end()) return relation->second; diff --git a/lib/osmparser/src/osmrelation.cpp b/lib/osmparser/src/osmrelation.cpp index 848cbab..87320e7 100644 --- a/lib/osmparser/src/osmrelation.cpp +++ b/lib/osmparser/src/osmrelation.cpp @@ -18,7 +18,7 @@ namespace osmp while (member_element != nullptr) { std::string memberType = GetSafeAttributeString(member_element, "type"); - unsigned int ref = GetSafeAttributeUint(member_element, "ref"); + uint64_t ref = GetSafeAttributeUint64(member_element, "ref"); std::string role = GetSafeAttributeString(member_element, "role"); std::shared_ptr member = nullptr; diff --git a/lib/osmparser/src/osmway.cpp b/lib/osmparser/src/osmway.cpp index bc8d44a..524d9f6 100644 --- a/lib/osmparser/src/osmway.cpp +++ b/lib/osmparser/src/osmway.cpp @@ -20,7 +20,7 @@ namespace osmp while (nd_elem != nullptr) { nodes.push_back( - parent->GetNode(GetSafeAttributeUint(nd_elem, "ref")) + parent->GetNode(GetSafeAttributeUint64(nd_elem, "ref")) ); nd_elem = nd_elem->NextSiblingElement("nd"); diff --git a/lib/osmparser/src/util.cpp b/lib/osmparser/src/util.cpp index d01e024..8490796 100644 --- a/lib/osmparser/src/util.cpp +++ b/lib/osmparser/src/util.cpp @@ -21,21 +21,20 @@ namespace osmp return returnStr; } - float GetSafeAttributeFloat(const tinyxml2::XMLElement* elem, const std::string& name) + double GetSafeAttributeFloat(const tinyxml2::XMLElement* elem, const std::string& name) { - float returnVal = 0.0f; + double returnVal = 0.0f; - xml::XMLError result = elem->QueryFloatAttribute(name.c_str(), &returnVal); + xml::XMLError result = elem->QueryDoubleAttribute(name.c_str(), &returnVal); return returnVal; } - unsigned int GetSafeAttributeUint(const tinyxml2::XMLElement* elem, const std::string& name) + uint64_t GetSafeAttributeUint64(const tinyxml2::XMLElement* elem, const std::string& name) { - unsigned int returnVal = 0; - - xml::XMLError result = elem->QueryUnsignedAttribute(name.c_str(), &returnVal); + uint64_t returnVal = 0; + xml::XMLError result = elem->QueryUnsigned64Attribute(name.c_str(), &returnVal); return returnVal; } diff --git a/lib/triangle/CMakeLists.txt b/lib/triangle/CMakeLists.txt index b9ad302..9e6095d 100644 --- a/lib/triangle/CMakeLists.txt +++ b/lib/triangle/CMakeLists.txt @@ -8,6 +8,8 @@ file(GLOB_RECURSE HPP_FILES "include/*.h" ) +SET_SOURCE_FILES_PROPERTIES( ${CPP_FILES} PROPERTIES LANGUAGE CXX ) + add_library(triangle STATIC ${CPP_FILES} ${HPP_FILES} ) diff --git a/lib/triangle/src/triangle.c b/lib/triangle/src/triangle.c index f7a5700..4190150 100644 --- a/lib/triangle/src/triangle.c +++ b/lib/triangle/src/triangle.c @@ -381,8 +381,8 @@ enum insertvertexresult {SUCCESSFULVERTEX, ENCROACHINGVERTEX, VIOLATINGVERTEX, /* Labels that signify the result of direction finding. The result */ /* indicates that a segment connecting the two query points falls within */ -/* the direction triangle, along the left edge of the direction triangle, */ -/* or along the right edge of the direction triangle. */ +/* the direction triangle, a__int64 the left edge of the direction triangle, */ +/* or a__int64 the right edge of the direction triangle. */ enum finddirectionresult {WITHIN, LEFTCOLLINEAR, RIGHTCOLLINEAR}; @@ -586,12 +586,12 @@ struct event { /* A node in the splay tree. Each node holds an oriented ghost triangle */ /* that represents a boundary edge of the growing triangulation. When a */ /* circle event covers two boundary edges with a triangle, so that they */ -/* are no longer boundary edges, those edges are not immediately deleted */ +/* are no __int64er boundary edges, those edges are not immediately deleted */ /* from the tree; rather, they are lazily deleted when they are next */ /* encountered. (Since only a random sample of boundary edges are kept */ /* in the tree, lazy deletion is faster.) `keydest' is used to verify */ /* that a triangle is still the same as when it entered the splay tree; if */ -/* it has been rotated (due to a circle event), it no longer represents a */ +/* it has been rotated (due to a circle event), it no __int64er represents a */ /* boundary edge and should be deleted. */ struct splaynode { @@ -633,7 +633,7 @@ struct memorypool { int itembytes; int itemsperblock; int itemsfirstblock; - long items, maxitems; + __int64 items, maxitems; int unallocateditems; int pathitemsleft; }; @@ -650,7 +650,7 @@ REAL o3derrboundA, o3derrboundB, o3derrboundC; /* Random number seed is not constant, but I've made it global anyway. */ -unsigned long randomseed; /* Current random number seed. */ +unsigned __int64 randomseed; /* Current random number seed. */ /* Mesh data structure. Triangle operates on only one mesh, but the mesh */ @@ -693,11 +693,11 @@ struct mesh { int holes; /* Number of input holes. */ int regions; /* Number of input regions. */ int undeads; /* Number of input vertices that don't appear in the mesh. */ - long edges; /* Number of output edges. */ + __int64 edges; /* Number of output edges. */ int mesh_dim; /* Dimension (ought to be 2). */ int nextras; /* Number of attributes per vertex. */ int eextras; /* Number of attributes per triangle. */ - long hullsize; /* Number of edges in convex hull. */ + __int64 hullsize; /* Number of edges in convex hull. */ int steinerleft; /* Number of Steiner points not yet used. */ int vertexmarkindex; /* Index to find boundary marker of a vertex. */ int vertex2triindex; /* Index to find a triangle adjacent to a vertex. */ @@ -707,14 +707,14 @@ struct mesh { int checksegments; /* Are there segments in the triangulation yet? */ int checkquality; /* Has quality triangulation begun yet? */ int readnodefile; /* Has a .node file been read? */ - long samples; /* Number of random samples for point location. */ + __int64 samples; /* Number of random samples for point location. */ - long incirclecount; /* Number of incircle tests performed. */ - long counterclockcount; /* Number of counterclockwise tests performed. */ - long orient3dcount; /* Number of 3D orientation tests performed. */ - long hyperbolacount; /* Number of right-of-hyperbola tests performed. */ - long circumcentercount; /* Number of circumcenter calculations performed. */ - long circletopcount; /* Number of circle top calculations performed. */ + __int64 incirclecount; /* Number of incircle tests performed. */ + __int64 counterclockcount; /* Number of counterclockwise tests performed. */ + __int64 orient3dcount; /* Number of 3D orientation tests performed. */ + __int64 hyperbolacount; /* Number of right-of-hyperbola tests performed. */ + __int64 circumcentercount; /* Number of circumcenter calculations performed. */ + __int64 circletopcount; /* Number of circle top calculations performed. */ /* Triangular bounding box vertices. */ @@ -827,8 +827,8 @@ struct behavior { /* extracting an orientation (in the range 0 to 2) and a pointer to the */ /* beginning of a triangle. The encode() routine compresses a pointer to a */ /* triangle and an orientation into a single pointer. My assumptions that */ -/* triangles are four-byte-aligned and that the `unsigned long' type is */ -/* long enough to hold a pointer are two of the few kludges in this program.*/ +/* triangles are four-byte-aligned and that the `unsigned __int64' type is */ +/* __int64 enough to hold a pointer are two of the few kludges in this program.*/ /* */ /* Subsegments are manipulated similarly. A pointer to a subsegment */ /* carries both an address and an orientation in the range 0 to 1. */ @@ -938,16 +938,16 @@ int minus1mod3[3] = {2, 0, 1}; /* extracted from the two least significant bits of the pointer. */ #define decode(ptr, otri) \ - (otri).orient = (int) ((unsigned long) (ptr) & (unsigned long) 3l); \ + (otri).orient = (int) ((unsigned __int64) (ptr) & (unsigned __int64) 3l); \ (otri).tri = (triangle *) \ - ((unsigned long) (ptr) ^ (unsigned long) (otri).orient) + ((unsigned __int64) (ptr) ^ (unsigned __int64) (otri).orient) /* encode() compresses an oriented triangle into a single pointer. It */ /* relies on the assumption that all triangles are aligned to four-byte */ /* boundaries, so the two least significant bits of (otri).tri are zero. */ #define encode(otri) \ - (triangle) ((unsigned long) (otri).tri | (unsigned long) (otri).orient) + (triangle) ((unsigned __int64) (otri).tri | (unsigned __int64) (otri).orient) /* The following handle manipulation primitives are all described by Guibas */ /* and Stolfi. However, Guibas and Stolfi use an edge-based data */ @@ -1111,16 +1111,16 @@ int minus1mod3[3] = {2, 0, 1}; #define infect(otri) \ (otri).tri[6] = (triangle) \ - ((unsigned long) (otri).tri[6] | (unsigned long) 2l) + ((unsigned __int64) (otri).tri[6] | (unsigned __int64) 2l) #define uninfect(otri) \ (otri).tri[6] = (triangle) \ - ((unsigned long) (otri).tri[6] & ~ (unsigned long) 2l) + ((unsigned __int64) (otri).tri[6] & ~ (unsigned __int64) 2l) /* Test a triangle for viral infection. */ #define infected(otri) \ - (((unsigned long) (otri).tri[6] & (unsigned long) 2l) != 0l) + (((unsigned __int64) (otri).tri[6] & (unsigned __int64) 2l) != 0l) /* Check or set a triangle's attributes. */ @@ -1158,16 +1158,16 @@ int minus1mod3[3] = {2, 0, 1}; /* are masked out to produce the real pointer. */ #define sdecode(sptr, osub) \ - (osub).ssorient = (int) ((unsigned long) (sptr) & (unsigned long) 1l); \ + (osub).ssorient = (int) ((unsigned __int64) (sptr) & (unsigned __int64) 1l); \ (osub).ss = (subseg *) \ - ((unsigned long) (sptr) & ~ (unsigned long) 3l) + ((unsigned __int64) (sptr) & ~ (unsigned __int64) 3l) /* sencode() compresses an oriented subsegment into a single pointer. It */ /* relies on the assumption that all subsegments are aligned to two-byte */ /* boundaries, so the least significant bit of (osub).ss is zero. */ #define sencode(osub) \ - (subseg) ((unsigned long) (osub).ss | (unsigned long) (osub).ssorient) + (subseg) ((unsigned __int64) (osub).ss | (unsigned __int64) (osub).ssorient) /* ssym() toggles the orientation of a subsegment. */ @@ -1386,7 +1386,7 @@ REAL area; /* The area of the triangle. */ oalen = dxoa * dxoa + dyoa * dyoa; dalen = dxda * dxda + dyda * dyda; odlen = dxod * dxod + dyod * dyod; - /* Find the square of the length of the longest edge. */ + /* Find the square of the length of the __int64est edge. */ maxlen = (dalen > oalen) ? dalen : oalen; maxlen = (odlen > maxlen) ? odlen : maxlen; @@ -1703,7 +1703,7 @@ void info() printf( " -A Assigns an additional floating-point attribute to each triangle\n"); printf( -" that identifies what segment-bounded region each triangle belongs\n"); +" that identifies what segment-bounded region each triangle be__int64s\n"); printf( " to. Attributes are assigned to regions by the .poly file. If a\n"); printf( @@ -2277,7 +2277,7 @@ void info() printf( " Triangle calculates the intersection points for you and adds them to\n"); printf( -" the triangulation--as long as your machine's floating-point precision\n"); +" the triangulation--as __int64 as your machine's floating-point precision\n"); printf( " doesn't become a problem. You are tempting the fates if you have three\n" ); @@ -3143,10 +3143,10 @@ void info() printf( " row of evenly spaced, segment-connected vertices? Have you simply\n"); printf( -" defined one long segment connecting the leftmost vertex to the rightmost\n" +" defined one __int64 segment connecting the leftmost vertex to the rightmost\n" ); printf( -" vertex, and a bunch of vertices lying along it? This method occasionally\n" +" vertex, and a bunch of vertices lying a__int64 it? This method occasionally\n" ); printf( " works, especially with horizontal and vertical lines, but often it\n"); @@ -3675,27 +3675,27 @@ struct otri *t; struct osub printsh; vertex printvertex; - printf("triangle x%lx with orientation %d:\n", (unsigned long) t->tri, + printf("triangle x%lx with orientation %d:\n", (unsigned __int64) t->tri, t->orient); decode(t->tri[0], printtri); if (printtri.tri == m->dummytri) { printf(" [0] = Outer space\n"); } else { - printf(" [0] = x%lx %d\n", (unsigned long) printtri.tri, + printf(" [0] = x%lx %d\n", (unsigned __int64) printtri.tri, printtri.orient); } decode(t->tri[1], printtri); if (printtri.tri == m->dummytri) { printf(" [1] = Outer space\n"); } else { - printf(" [1] = x%lx %d\n", (unsigned long) printtri.tri, + printf(" [1] = x%lx %d\n", (unsigned __int64) printtri.tri, printtri.orient); } decode(t->tri[2], printtri); if (printtri.tri == m->dummytri) { printf(" [2] = Outer space\n"); } else { - printf(" [2] = x%lx %d\n", (unsigned long) printtri.tri, + printf(" [2] = x%lx %d\n", (unsigned __int64) printtri.tri, printtri.orient); } @@ -3704,37 +3704,37 @@ struct otri *t; printf(" Origin[%d] = NULL\n", (t->orient + 1) % 3 + 3); else printf(" Origin[%d] = x%lx (%.12g, %.12g)\n", - (t->orient + 1) % 3 + 3, (unsigned long) printvertex, + (t->orient + 1) % 3 + 3, (unsigned __int64) printvertex, printvertex[0], printvertex[1]); dest(*t, printvertex); if (printvertex == (vertex) NULL) printf(" Dest [%d] = NULL\n", (t->orient + 2) % 3 + 3); else printf(" Dest [%d] = x%lx (%.12g, %.12g)\n", - (t->orient + 2) % 3 + 3, (unsigned long) printvertex, + (t->orient + 2) % 3 + 3, (unsigned __int64) printvertex, printvertex[0], printvertex[1]); apex(*t, printvertex); if (printvertex == (vertex) NULL) printf(" Apex [%d] = NULL\n", t->orient + 3); else printf(" Apex [%d] = x%lx (%.12g, %.12g)\n", - t->orient + 3, (unsigned long) printvertex, + t->orient + 3, (unsigned __int64) printvertex, printvertex[0], printvertex[1]); if (b->usesegments) { sdecode(t->tri[6], printsh); if (printsh.ss != m->dummysub) { - printf(" [6] = x%lx %d\n", (unsigned long) printsh.ss, + printf(" [6] = x%lx %d\n", (unsigned __int64) printsh.ss, printsh.ssorient); } sdecode(t->tri[7], printsh); if (printsh.ss != m->dummysub) { - printf(" [7] = x%lx %d\n", (unsigned long) printsh.ss, + printf(" [7] = x%lx %d\n", (unsigned __int64) printsh.ss, printsh.ssorient); } sdecode(t->tri[8], printsh); if (printsh.ss != m->dummysub) { - printf(" [8] = x%lx %d\n", (unsigned long) printsh.ss, + printf(" [8] = x%lx %d\n", (unsigned __int64) printsh.ss, printsh.ssorient); } } @@ -3770,19 +3770,19 @@ struct osub *s; vertex printvertex; printf("subsegment x%lx with orientation %d and mark %d:\n", - (unsigned long) s->ss, s->ssorient, mark(*s)); + (unsigned __int64) s->ss, s->ssorient, mark(*s)); sdecode(s->ss[0], printsh); if (printsh.ss == m->dummysub) { printf(" [0] = No subsegment\n"); } else { - printf(" [0] = x%lx %d\n", (unsigned long) printsh.ss, + printf(" [0] = x%lx %d\n", (unsigned __int64) printsh.ss, printsh.ssorient); } sdecode(s->ss[1], printsh); if (printsh.ss == m->dummysub) { printf(" [1] = No subsegment\n"); } else { - printf(" [1] = x%lx %d\n", (unsigned long) printsh.ss, + printf(" [1] = x%lx %d\n", (unsigned __int64) printsh.ss, printsh.ssorient); } @@ -3791,28 +3791,28 @@ struct osub *s; printf(" Origin[%d] = NULL\n", 2 + s->ssorient); else printf(" Origin[%d] = x%lx (%.12g, %.12g)\n", - 2 + s->ssorient, (unsigned long) printvertex, + 2 + s->ssorient, (unsigned __int64) printvertex, printvertex[0], printvertex[1]); sdest(*s, printvertex); if (printvertex == (vertex) NULL) printf(" Dest [%d] = NULL\n", 3 - s->ssorient); else printf(" Dest [%d] = x%lx (%.12g, %.12g)\n", - 3 - s->ssorient, (unsigned long) printvertex, + 3 - s->ssorient, (unsigned __int64) printvertex, printvertex[0], printvertex[1]); decode(s->ss[6], printtri); if (printtri.tri == m->dummytri) { printf(" [6] = Outer space\n"); } else { - printf(" [6] = x%lx %d\n", (unsigned long) printtri.tri, + printf(" [6] = x%lx %d\n", (unsigned __int64) printtri.tri, printtri.orient); } decode(s->ss[7], printtri); if (printtri.tri == m->dummytri) { printf(" [7] = Outer space\n"); } else { - printf(" [7] = x%lx %d\n", (unsigned long) printtri.tri, + printf(" [7] = x%lx %d\n", (unsigned __int64) printtri.tri, printtri.orient); } @@ -3821,14 +3821,14 @@ struct osub *s; printf(" Segment origin[%d] = NULL\n", 4 + s->ssorient); else printf(" Segment origin[%d] = x%lx (%.12g, %.12g)\n", - 4 + s->ssorient, (unsigned long) printvertex, + 4 + s->ssorient, (unsigned __int64) printvertex, printvertex[0], printvertex[1]); segdest(*s, printvertex); if (printvertex == (vertex) NULL) printf(" Segment dest [%d] = NULL\n", 5 - s->ssorient); else printf(" Segment dest [%d] = x%lx (%.12g, %.12g)\n", - 5 - s->ssorient, (unsigned long) printvertex, + 5 - s->ssorient, (unsigned __int64) printvertex, printvertex[0], printvertex[1]); } @@ -3891,7 +3891,7 @@ struct memorypool *pool; #endif /* not ANSI_DECLARATORS */ { - unsigned long alignptr; + unsigned __int64 alignptr; pool->items = 0; pool->maxitems = 0; @@ -3899,11 +3899,11 @@ struct memorypool *pool; /* Set the currently active block. */ pool->nowblock = pool->firstblock; /* Find the first item in the pool. Increment by the size of (VOID *). */ - alignptr = (unsigned long) (pool->nowblock + 1); + alignptr = (unsigned __int64) (pool->nowblock + 1); /* Align the item on an `alignbytes'-byte boundary. */ pool->nextitem = (VOID *) - (alignptr + (unsigned long) pool->alignbytes - - (alignptr % (unsigned long) pool->alignbytes)); + (alignptr + (unsigned __int64) pool->alignbytes - + (alignptr % (unsigned __int64) pool->alignbytes)); /* There are lots of unallocated items left in this block. */ pool->unallocateditems = pool->itemsfirstblock; /* The stack of deallocated items is empty. */ @@ -4008,7 +4008,7 @@ struct memorypool *pool; { VOID *newitem; VOID **newblock; - unsigned long alignptr; + unsigned __int64 alignptr; /* First check the linked list of dead items. If the list is not */ /* empty, allocate an item from the list rather than a fresh one. */ @@ -4033,11 +4033,11 @@ struct memorypool *pool; pool->nowblock = (VOID **) *(pool->nowblock); /* Find the first item in the block. */ /* Increment by the size of (VOID *). */ - alignptr = (unsigned long) (pool->nowblock + 1); + alignptr = (unsigned __int64) (pool->nowblock + 1); /* Align the item on an `alignbytes'-byte boundary. */ pool->nextitem = (VOID *) - (alignptr + (unsigned long) pool->alignbytes - - (alignptr % (unsigned long) pool->alignbytes)); + (alignptr + (unsigned __int64) pool->alignbytes - + (alignptr % (unsigned __int64) pool->alignbytes)); /* There are lots of unallocated items left in this block. */ pool->unallocateditems = pool->itemsperblock; } @@ -4092,16 +4092,16 @@ struct memorypool *pool; #endif /* not ANSI_DECLARATORS */ { - unsigned long alignptr; + unsigned __int64 alignptr; /* Begin the traversal in the first block. */ pool->pathblock = pool->firstblock; /* Find the first item in the block. Increment by the size of (VOID *). */ - alignptr = (unsigned long) (pool->pathblock + 1); + alignptr = (unsigned __int64) (pool->pathblock + 1); /* Align with item on an `alignbytes'-byte boundary. */ pool->pathitem = (VOID *) - (alignptr + (unsigned long) pool->alignbytes - - (alignptr % (unsigned long) pool->alignbytes)); + (alignptr + (unsigned __int64) pool->alignbytes - + (alignptr % (unsigned __int64) pool->alignbytes)); /* Set the number of items left in the current block. */ pool->pathitemsleft = pool->itemsfirstblock; } @@ -4129,7 +4129,7 @@ struct memorypool *pool; { VOID *newitem; - unsigned long alignptr; + unsigned __int64 alignptr; /* Stop upon exhausting the list of items. */ if (pool->pathitem == pool->nextitem) { @@ -4141,11 +4141,11 @@ struct memorypool *pool; /* Find the next block. */ pool->pathblock = (VOID **) *(pool->pathblock); /* Find the first item in the block. Increment by the size of (VOID *). */ - alignptr = (unsigned long) (pool->pathblock + 1); + alignptr = (unsigned __int64) (pool->pathblock + 1); /* Align with item on an `alignbytes'-byte boundary. */ pool->pathitem = (VOID *) - (alignptr + (unsigned long) pool->alignbytes - - (alignptr % (unsigned long) pool->alignbytes)); + (alignptr + (unsigned __int64) pool->alignbytes - + (alignptr % (unsigned __int64) pool->alignbytes)); /* Set the number of items left in the current block. */ pool->pathitemsleft = pool->itemsperblock; } @@ -4197,19 +4197,19 @@ int subsegbytes; #endif /* not ANSI_DECLARATORS */ { - unsigned long alignptr; + unsigned __int64 alignptr; /* Set up `dummytri', the `triangle' that occupies "outer space." */ m->dummytribase = (triangle *) trimalloc(trianglebytes + m->triangles.alignbytes); /* Align `dummytri' on a `triangles.alignbytes'-byte boundary. */ - alignptr = (unsigned long) m->dummytribase; + alignptr = (unsigned __int64) m->dummytribase; m->dummytri = (triangle *) - (alignptr + (unsigned long) m->triangles.alignbytes - - (alignptr % (unsigned long) m->triangles.alignbytes)); + (alignptr + (unsigned __int64) m->triangles.alignbytes - + (alignptr % (unsigned __int64) m->triangles.alignbytes)); /* Initialize the three adjoining triangles to be "outer space." These */ /* will eventually be changed by various bonding operations, but their */ - /* values don't really matter, as long as they can legally be */ + /* values don't really matter, as __int64 as they can legally be */ /* dereferenced. */ m->dummytri[0] = (triangle) m->dummytri; m->dummytri[1] = (triangle) m->dummytri; @@ -4226,13 +4226,13 @@ int subsegbytes; m->dummysubbase = (subseg *) trimalloc(subsegbytes + m->subsegs.alignbytes); /* Align `dummysub' on a `subsegs.alignbytes'-byte boundary. */ - alignptr = (unsigned long) m->dummysubbase; + alignptr = (unsigned __int64) m->dummysubbase; m->dummysub = (subseg *) - (alignptr + (unsigned long) m->subsegs.alignbytes - - (alignptr % (unsigned long) m->subsegs.alignbytes)); + (alignptr + (unsigned __int64) m->subsegs.alignbytes - + (alignptr % (unsigned __int64) m->subsegs.alignbytes)); /* Initialize the two adjoining subsegments to be the omnipresent */ /* subsegment. These will eventually be changed by various bonding */ - /* operations, but their values don't really matter, as long as they */ + /* operations, but their values don't really matter, as __int64 as they */ /* can legally be dereferenced. */ m->dummysub[0] = (subseg) m->dummysub; m->dummysub[1] = (subseg) m->dummysub; @@ -4586,7 +4586,7 @@ int number; { VOID **getblock; char *foundvertex; - unsigned long alignptr; + unsigned __int64 alignptr; int current; getblock = m->vertices.firstblock; @@ -4603,9 +4603,9 @@ int number; } /* Now find the right vertex. */ - alignptr = (unsigned long) (getblock + 1); - foundvertex = (char *) (alignptr + (unsigned long) m->vertices.alignbytes - - (alignptr % (unsigned long) m->vertices.alignbytes)); + alignptr = (unsigned __int64) (getblock + 1); + foundvertex = (char *) (alignptr + (unsigned __int64) m->vertices.alignbytes - + (alignptr % (unsigned __int64) m->vertices.alignbytes)); return (vertex) (foundvertex + m->vertices.itembytes * (number - current)); } @@ -6506,8 +6506,8 @@ vertex pd; /* The result is returned both in terms of x-y coordinates and xi-eta */ /* (barycentric) coordinates. The xi-eta coordinate system is defined in */ /* terms of the triangle: the origin of the triangle is the origin of the */ -/* coordinate system; the destination of the triangle is one unit along the */ -/* xi axis; and the apex of the triangle is one unit along the eta axis. */ +/* coordinate system; the destination of the triangle is one unit a__int64 the */ +/* xi axis; and the apex of the triangle is one unit a__int64 the eta axis. */ /* This procedure also returns the square of the length of the triangle's */ /* shortest edge. */ /* */ @@ -6667,9 +6667,9 @@ struct mesh *m; /*****************************************************************************/ #ifdef ANSI_DECLARATORS -unsigned long randomnation(unsigned int choices) +unsigned __int64 randomnation(unsigned int choices) #else /* not ANSI_DECLARATORS */ -unsigned long randomnation(choices) +unsigned __int64 randomnation(choices) unsigned int choices; #endif /* not ANSI_DECLARATORS */ @@ -7485,7 +7485,7 @@ struct behavior *b; /* WARNING: This routine is designed for convex triangulations, and will */ /* not generally work after the holes and concavities have been carved. */ /* However, it can still be used to find the circumcenter of a triangle, as */ -/* long as the search is begun from the triangle in question. */ +/* __int64 as the search is begun from the triangle in question. */ /* */ /*****************************************************************************/ @@ -7649,11 +7649,11 @@ struct otri *searchtri; char *firsttri; struct otri sampletri; vertex torg, tdest; - unsigned long alignptr; + unsigned __int64 alignptr; REAL searchdist, dist; REAL ahead; - long samplesperblock, totalsamplesleft, samplesleft; - long population, totalpopulation; + __int64 samplesperblock, totalsamplesleft, samplesleft; + __int64 population, totalpopulation; triangle ptr; /* Temporary variable used by sym(). */ if (b->verbose > 2) { @@ -7721,11 +7721,11 @@ struct otri *searchtri; population = totalpopulation; } /* Find a pointer to the first triangle in the block. */ - alignptr = (unsigned long) (sampleblock + 1); + alignptr = (unsigned __int64) (sampleblock + 1); firsttri = (char *) (alignptr + - (unsigned long) m->triangles.alignbytes - + (unsigned __int64) m->triangles.alignbytes - (alignptr % - (unsigned long) m->triangles.alignbytes)); + (unsigned __int64) m->triangles.alignbytes)); /* Choose `samplesleft' randomly sampled triangles in this block. */ do { @@ -8699,7 +8699,7 @@ int triflaws; } else { /* Take the average of the two triangles' area constraints. */ /* This prevents small area constraints from migrating a */ - /* long, long way from their original location due to flips. */ + /* __int64, __int64 way from their original location due to flips. */ area = 0.5 * (areabound(top) + areabound(horiz)); } setareabound(top, area); @@ -8807,7 +8807,7 @@ int triflaws; /* polygon, until `lastedge', the primary edge of the last triangle. */ /* `firstedge' and `lastedge' are probably connected to other triangles */ /* beyond the extremes of the fan, but their identity is not important, as */ -/* long as the fan remains connected to them. */ +/* __int64 as the fan remains connected to them. */ /* */ /* Imagine the polygon oriented so that its base is at the bottom. This */ /* puts `firstedge' on the far right, and `lastedge' on the far left. */ @@ -8839,7 +8839,7 @@ int triflaws; /* O(n^2) time not only in the worst case, but in many common cases. It's */ /* rarely a big deal for vertex deletion, where n is rarely larger than */ /* ten, but it could be a big deal for segment insertion, especially if */ -/* there's a lot of long segments that each cut many triangles. I ought to */ +/* there's a lot of __int64 segments that each cut many triangles. I ought to */ /* code a faster algorithm some day. */ /* */ /* The `edgecount' parameter is the number of sides of the polygon, */ @@ -9906,9 +9906,9 @@ struct otri *farright; } #ifdef ANSI_DECLARATORS -long removeghosts(struct mesh *m, struct behavior *b, struct otri *startghost) +__int64 removeghosts(struct mesh *m, struct behavior *b, struct otri *startghost) #else /* not ANSI_DECLARATORS */ -long removeghosts(m, b, startghost) +__int64 removeghosts(m, b, startghost) struct mesh *m; struct behavior *b; struct otri *startghost; @@ -9919,7 +9919,7 @@ struct otri *startghost; struct otri dissolveedge; struct otri deadtriangle; vertex markorg; - long hullsize; + __int64 hullsize; triangle ptr; /* Temporary variable used by sym(). */ if (b->verbose) { @@ -9969,9 +9969,9 @@ struct otri *startghost; /*****************************************************************************/ #ifdef ANSI_DECLARATORS -long divconqdelaunay(struct mesh *m, struct behavior *b) +__int64 divconqdelaunay(struct mesh *m, struct behavior *b) #else /* not ANSI_DECLARATORS */ -long divconqdelaunay(m, b) +__int64 divconqdelaunay(m, b) struct mesh *m; struct behavior *b; #endif /* not ANSI_DECLARATORS */ @@ -10122,9 +10122,9 @@ struct behavior *b; #ifndef REDUCED #ifdef ANSI_DECLARATORS -long removebox(struct mesh *m, struct behavior *b) +__int64 removebox(struct mesh *m, struct behavior *b) #else /* not ANSI_DECLARATORS */ -long removebox(m, b) +__int64 removebox(m, b) struct mesh *m; struct behavior *b; #endif /* not ANSI_DECLARATORS */ @@ -10135,7 +10135,7 @@ struct behavior *b; struct otri checkedge; struct otri nextedge, finaledge, dissolveedge; vertex markorg; - long hullsize; + __int64 hullsize; triangle ptr; /* Temporary variable used by sym(). */ if (b->verbose) { @@ -10221,9 +10221,9 @@ struct behavior *b; #ifndef REDUCED #ifdef ANSI_DECLARATORS -long incrementaldelaunay(struct mesh *m, struct behavior *b) +__int64 incrementaldelaunay(struct mesh *m, struct behavior *b) #else /* not ANSI_DECLARATORS */ -long incrementaldelaunay(m, b) +__int64 incrementaldelaunay(m, b) struct mesh *m; struct behavior *b; #endif /* not ANSI_DECLARATORS */ @@ -10785,9 +10785,9 @@ int *farright; #ifndef REDUCED #ifdef ANSI_DECLARATORS -long sweeplinedelaunay(struct mesh *m, struct behavior *b) +__int64 sweeplinedelaunay(struct mesh *m, struct behavior *b) #else /* not ANSI_DECLARATORS */ -long sweeplinedelaunay(m, b) +__int64 sweeplinedelaunay(m, b) struct mesh *m; struct behavior *b; #endif /* not ANSI_DECLARATORS */ @@ -11013,15 +11013,15 @@ struct behavior *b; /*****************************************************************************/ #ifdef ANSI_DECLARATORS -long delaunay(struct mesh *m, struct behavior *b) +__int64 delaunay(struct mesh *m, struct behavior *b) #else /* not ANSI_DECLARATORS */ -long delaunay(m, b) +__int64 delaunay(m, b) struct mesh *m; struct behavior *b; #endif /* not ANSI_DECLARATORS */ { - long hulledges; + __int64 hulledges; m->eextras = 0; initializetrisubpools(m, b); @@ -11114,10 +11114,10 @@ int numberofsegments; #else /* not TRILIBRARY */ #ifdef ANSI_DECLARATORS -long reconstruct(struct mesh *m, struct behavior *b, char *elefilename, +__int64 reconstruct(struct mesh *m, struct behavior *b, char *elefilename, char *areafilename, char *polyfilename, FILE *polyfile) #else /* not ANSI_DECLARATORS */ -long reconstruct(m, b, elefilename, areafilename, polyfilename, polyfile) +__int64 reconstruct(m, b, elefilename, areafilename, polyfilename, polyfile) struct mesh *m; struct behavior *b; char *elefilename; @@ -11161,9 +11161,9 @@ FILE *polyfile; int segmentmarkers; int boundmarker; int aroundvertex; - long hullsize; + __int64 hullsize; int notfound; - long elementnumber, segmentnumber; + __int64 elementnumber, segmentnumber; int i, j; triangle ptr; /* Temporary variable used by sym(). */ @@ -12113,7 +12113,7 @@ int leftside; /* encountered. This step creates a fan of edges connected to endpoint1, */ /* including the desired edge to endpoint2. The second step enforces the */ /* Delaunay condition on each side of the segment in an incremental manner: */ -/* proceeding along the polygon from endpoint1 to endpoint2 (this is done */ +/* proceeding a__int64 the polygon from endpoint1 to endpoint2 (this is done */ /* independently on each side of the segment), each vertex is "enforced" */ /* as if it had just been inserted, but affecting only the previous */ /* vertices. The result is the same as if the vertices had been inserted */ @@ -13060,7 +13060,7 @@ int regions; } /* Now, we have to find all the regions BEFORE we carve the holes, because */ - /* locate() won't work when the triangulation is no longer convex. */ + /* locate() won't work when the triangulation is no __int64er convex. */ /* (Incidentally, this is the reason why regional attributes and area */ /* constraints can't be used when refining a preexisting mesh, which */ /* might not be convex; they can only be used with a freshly */ @@ -13541,7 +13541,7 @@ struct badtriang *badtri; setvertexmark(newvertex, 0); setvertextype(newvertex, FREEVERTEX); - /* Ensure that the handle `badotri' does not represent the longest */ + /* Ensure that the handle `badotri' does not represent the __int64est */ /* edge of the triangle. This ensures that the circumcenter must */ /* fall to the left of this edge, so point location will work. */ /* (If the angle org-apex-dest exceeds 90 degrees, then the */ @@ -14358,7 +14358,7 @@ char **argv; FILE *outfile; #endif /* not TRILIBRARY */ vertex vertexloop; - long outvertices; + __int64 outvertices; int vertexnumber; int i; @@ -14530,7 +14530,7 @@ char **argv; struct otri triangleloop; vertex p1, p2, p3; vertex mid1, mid2, mid3; - long elementnumber; + __int64 elementnumber; int i; #ifdef TRILIBRARY @@ -14672,11 +14672,11 @@ char **argv; int index; #else /* not TRILIBRARY */ FILE *outfile; - long holenumber, regionnumber; + __int64 holenumber, regionnumber; #endif /* not TRILIBRARY */ struct osub subsegloop; vertex endpoint1, endpoint2; - long subsegnumber; + __int64 subsegnumber; #ifdef TRILIBRARY if (!b->quiet) { @@ -14816,7 +14816,7 @@ char **argv; struct otri triangleloop, trisym; struct osub checkmark; vertex p1, p2; - long edgenumber; + __int64 edgenumber; triangle ptr; /* Temporary variable used by sym(). */ subseg sptr; /* Temporary variable used by tspivot(). */ @@ -14981,7 +14981,7 @@ char **argv; vertex torg, tdest, tapex; REAL circumcenter[2]; REAL xi, eta; - long vnodenumber, vedgenumber; + __int64 vnodenumber, vedgenumber; int p1, p2; int i; triangle ptr; /* Temporary variable used by sym(). */ @@ -15178,7 +15178,7 @@ char **argv; FILE *outfile; #endif /* not TRILIBRARY */ struct otri triangleloop, trisym; - long elementnumber; + __int64 elementnumber; int neighbor1, neighbor2, neighbor3; triangle ptr; /* Temporary variable used by sym(). */ @@ -15277,7 +15277,7 @@ char **argv; struct otri triangleloop; vertex vertexloop; vertex p1, p2, p3; - long outvertices; + __int64 outvertices; if (!b->quiet) { printf("Writing %s.\n", offfilename); @@ -15356,8 +15356,8 @@ struct behavior *b; REAL dotproduct; REAL cossquare; REAL triarea; - REAL shortest, longest; - REAL trilongest2; + REAL shortest, __int64est; + REAL tri__int64est2; REAL smallestarea, biggestarea; REAL triminaltitude2; REAL minaltitude; @@ -15399,7 +15399,7 @@ struct behavior *b; minaltitude = m->xmax - m->xmin + m->ymax - m->ymin; minaltitude = minaltitude * minaltitude; shortest = minaltitude; - longest = 0.0; + __int64est = 0.0; smallestarea = minaltitude; biggestarea = 0.0; worstaspect = 0.0; @@ -15414,7 +15414,7 @@ struct behavior *b; org(triangleloop, p[0]); dest(triangleloop, p[1]); apex(triangleloop, p[2]); - trilongest2 = 0.0; + tri__int64est2 = 0.0; for (i = 0; i < 3; i++) { j = plus1mod3[i]; @@ -15422,11 +15422,11 @@ struct behavior *b; dx[i] = p[j][0] - p[k][0]; dy[i] = p[j][1] - p[k][1]; edgelength[i] = dx[i] * dx[i] + dy[i] * dy[i]; - if (edgelength[i] > trilongest2) { - trilongest2 = edgelength[i]; + if (edgelength[i] > tri__int64est2) { + tri__int64est2 = edgelength[i]; } - if (edgelength[i] > longest) { - longest = edgelength[i]; + if (edgelength[i] > __int64est) { + __int64est = edgelength[i]; } if (edgelength[i] < shortest) { shortest = edgelength[i]; @@ -15440,11 +15440,11 @@ struct behavior *b; if (triarea > biggestarea) { biggestarea = triarea; } - triminaltitude2 = triarea * triarea / trilongest2; + triminaltitude2 = triarea * triarea / tri__int64est2; if (triminaltitude2 < minaltitude) { minaltitude = triminaltitude2; } - triaspect2 = trilongest2 / triminaltitude2; + triaspect2 = tri__int64est2 / triminaltitude2; if (triaspect2 > worstaspect) { worstaspect = triaspect2; } @@ -15486,7 +15486,7 @@ struct behavior *b; } shortest = sqrt(shortest); - longest = sqrt(longest); + __int64est = sqrt(__int64est); minaltitude = sqrt(minaltitude); worstaspect = sqrt(worstaspect); smallestarea *= 0.5; @@ -15508,8 +15508,8 @@ struct behavior *b; printf(" Smallest area: %16.5g | Largest area: %16.5g\n", smallestarea, biggestarea); - printf(" Shortest edge: %16.5g | Longest edge: %16.5g\n", - shortest, longest); + printf(" Shortest edge: %16.5g | __int64est edge: %16.5g\n", + shortest, __int64est); printf(" Shortest altitude: %12.5g | Largest aspect ratio: %8.5g\n\n", minaltitude, worstaspect); @@ -15525,7 +15525,7 @@ struct behavior *b; printf(" %6.6g - %-6.6g : %8d | %6.6g - : %8d\n", ratiotable[6], ratiotable[7], aspecttable[7], ratiotable[14], aspecttable[15]); - printf(" (Aspect ratio is longest edge divided by shortest altitude)\n\n"); + printf(" (Aspect ratio is __int64est edge divided by shortest altitude)\n\n"); printf(" Smallest angle: %15.5g | Largest angle: %15.5g\n\n", smallestangle, biggestangle); diff --git a/src/main.cpp b/src/main.cpp index 716a7fd..b3e3b07 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -259,6 +259,10 @@ int main(int argc, char** argv) SDL_SetRenderDrawColor(renderer, railway.r, railway.g, railway.b, 255); SDL_RenderDrawLinesF(renderer, railway.points, railway.length); } + + for (Multipolygon& multipolygon : multipolygons) { + multipolygon.Draw(renderer, 255, 0, 0); + } SDL_RenderPresent(renderer); diff --git a/src/multipolygon.cpp b/src/multipolygon.cpp index 7ed00f0..2b1a130 100644 --- a/src/multipolygon.cpp +++ b/src/multipolygon.cpp @@ -5,13 +5,16 @@ #include #include #include +#include +#include struct TriangulationData { std::vector vertices, holes; + std::vector segments; }; // Map values from one interval [A, B] to another [a, b] -inline float Map(float A, float B, float a, float b, float x) +inline double Map(double A, double B, double a, double b, double x) { return (x - A) * (b - a) / (B - A) + a; } @@ -22,9 +25,17 @@ Multipolygon::Multipolygon(const std::shared_ptr& relation, int return; std::vector data; + + if (relation->id == 3363659) { + __debugbreak(); + } const std::vector& ways = relation->GetWays(); std::vector> nodes; + std::shared_ptr lastNode = nullptr; + std::shared_ptr nextNode = nullptr; + int run = 1; + int total = 0; for (osmp::Relation::Member member : ways) { std::shared_ptr way = std::dynamic_pointer_cast(member.member); @@ -42,21 +53,41 @@ Multipolygon::Multipolygon(const std::shared_ptr& relation, int // Continue with Closed way algorithm bool inner = (member.role == "inner"); - const std::vector> wayNodes = way->GetNodes(); - nodes.insert(nodes.end(), wayNodes.begin(), wayNodes.end()); + std::vector> wayNodes = way->GetNodes(); + + if (run == 1) { + nodes.insert(nodes.begin(), wayNodes.begin(), wayNodes.end()); + } + else { + if (nodes.back() == wayNodes.front()) { + nodes.insert(nodes.end(), wayNodes.begin() + 1, wayNodes.end()); + } + else if (nodes.back() == wayNodes.back()) { + nodes.insert(nodes.end(), wayNodes.rbegin() + 1, wayNodes.rend()); + } + else if (nodes.front() == wayNodes.back()) { + nodes.insert(nodes.begin(), wayNodes.begin(), wayNodes.end() - 1); + } + else /*if (nodes.front() == wayNodes.front())*/ { + nodes.insert(nodes.begin(), wayNodes.rbegin(), wayNodes.rend() - 1); + } + } + + run++; if (!(way->closed)) { - if (nodes.front() == nodes.back()) + if (nodes.size() > 1 && nodes.front() == nodes.back()) { - nodes.pop_back(); + // nodes.pop_back(); } else { continue; } } + nodes.pop_back(); - if (!inner) + if (!inner || data.empty()) { data.push_back({}); } @@ -86,30 +117,73 @@ Multipolygon::Multipolygon(const std::shared_ptr& relation, int td.holes.push_back(holeY); } + // Get segments + int segNum = td.vertices.size() / 2; + for (int i = 0; i < vertices.size(); i += 2) { + td.segments.push_back(segNum); + td.segments.push_back(++segNum); + } + td.segments.back() = td.vertices.size() / 2; + td.vertices.insert(td.vertices.end(), vertices.begin(), vertices.end()); nodes.clear(); + lastNode = nullptr; + run = 1; } - char* triswitches = "zp"; + char* triswitches = "zpNBV"; for (TriangulationData& td : data) { triangulateio in; in.numberofpoints = td.vertices.size() / 2; in.pointlist = td.vertices.data(); + in.pointmarkerlist = NULL; in.numberofpointattributes = 0; in.numberofpointattributes = NULL; - in.numberofholes = td.vertices.size() / 2; + in.numberofholes = td.holes.size() / 2; in.holelist = td.holes.data(); + in.numberofsegments = td.segments.size() / 2; + in.segmentlist = td.segments.data(); + in.segmentmarkerlist = NULL; + in.numberofregions = 0; in.regionlist = NULL; triangulateio out; + out.pointlist = NULL; + out.pointmarkerlist = NULL; + out.trianglelist = NULL; + out.segmentlist = NULL; + out.segmentmarkerlist = NULL; triangulate(triswitches, &in, &out, NULL); - volatile int lol = 3; + // TODO: memory leak go brrrr + polygons.push_back({}); + for (int i = 0; i < in.numberofpoints * 2; i += 2) { + polygons.back().vertices.push_back({ in.pointlist[i], in.pointlist[i + 1] }); + // polygons.back().vertices.push_back(in.pointlist[i + 1]); + } + for (int i = 0; i < out.numberoftriangles * 3; i++) { + polygons.back().indices.push_back(out.trianglelist[i]); + } + } +} + +void Multipolygon::Draw(SDL_Renderer* renderer, int r, int g, int b) +{ + for (const Polygon& polygon : polygons) { + for (int i = 0; i < polygon.indices.size(); i += 3) // Be a graphics card + { + filledTrigonRGBA(renderer, + polygon.vertices[polygon.indices[i + 0]].x, polygon.vertices[polygon.indices[i + 0]].y, + polygon.vertices[polygon.indices[i + 1]].x, polygon.vertices[polygon.indices[i + 1]].y, + polygon.vertices[polygon.indices[i + 2]].x, polygon.vertices[polygon.indices[i + 2]].y, + r, g, b, 255 + ); + } } }