プログレス。。。

This commit is contained in:
Robert 2021-04-17 03:15:07 +02:00
parent 19a188e059
commit fe87e22b16
14 changed files with 271 additions and 179 deletions

View file

@ -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);

View file

@ -5,13 +5,16 @@
#include <triangle.h>
#include <osmway.hpp>
#include <osmnode.hpp>
#include <SDL.h>
#include <SDL2_gfxPrimitives.h>
struct TriangulationData {
std::vector<REAL> vertices, holes;
std::vector<int> 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<osmp::Relation>& relation, int
return;
std::vector<TriangulationData> data;
if (relation->id == 3363659) {
__debugbreak();
}
const std::vector<osmp::Relation::Member>& ways = relation->GetWays();
std::vector<std::shared_ptr<osmp::Node>> nodes;
std::shared_ptr<osmp::Node> lastNode = nullptr;
std::shared_ptr<osmp::Way> nextNode = nullptr;
int run = 1;
int total = 0;
for (osmp::Relation::Member member : ways)
{
std::shared_ptr<osmp::Way> way = std::dynamic_pointer_cast<osmp::Way>(member.member);
@ -42,21 +53,41 @@ Multipolygon::Multipolygon(const std::shared_ptr<osmp::Relation>& relation, int
// Continue with Closed way algorithm
bool inner = (member.role == "inner");
const std::vector<std::shared_ptr<osmp::Node>> wayNodes = way->GetNodes();
nodes.insert(nodes.end(), wayNodes.begin(), wayNodes.end());
std::vector<std::shared_ptr<osmp::Node>> 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<osmp::Relation>& 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
);
}
}
}