Finished multipolygon assembly
This commit is contained in:
parent
e7d189dc8b
commit
079d5f2b99
|
@ -178,10 +178,10 @@ int main(int argc, char** argv)
|
||||||
multipolygon.Draw(renderer);
|
multipolygon.Draw(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
//for (Area& area : buildings)
|
for (Area& area : buildings)
|
||||||
//{
|
{
|
||||||
// filledPolygonRGBA(renderer, area.x, area.y, area.length, area.r, area.g, area.b, 255);
|
filledPolygonRGBA(renderer, area.x, area.y, area.length, area.r, area.g, area.b, 255);
|
||||||
//}
|
}
|
||||||
|
|
||||||
for (Highway& highway : highways)
|
for (Highway& highway : highways)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,8 @@ struct TriangulationData {
|
||||||
struct Ring {
|
struct Ring {
|
||||||
osmp::Nodes nodes;
|
osmp::Nodes nodes;
|
||||||
bool inner;
|
bool inner;
|
||||||
|
int index;
|
||||||
|
bool hole = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RingGroup {
|
struct RingGroup {
|
||||||
|
@ -40,12 +42,15 @@ inline double Map(double A, double B, double a, double b, double x)
|
||||||
[[nodiscard]] bool Intersect(const osmp::Node& p1, const osmp::Node& p2, const osmp::Node& q1, const osmp::Node& q2);
|
[[nodiscard]] bool Intersect(const osmp::Node& p1, const osmp::Node& p2, const osmp::Node& q1, const osmp::Node& q2);
|
||||||
[[nodiscard]] bool SelfIntersecting(const Ring& ring);
|
[[nodiscard]] bool SelfIntersecting(const Ring& ring);
|
||||||
|
|
||||||
[[nodiscard]] bool BuildRing(Ring& ring, osmp::MemberWays& unassigned);
|
[[nodiscard]] bool BuildRing(Ring& ring, osmp::MemberWays& unassigned, int ringCount);
|
||||||
[[nodiscard]] bool AssignRings(std::vector<Ring>& rings, const osmp::MemberWays& members);
|
[[nodiscard]] bool AssignRings(std::vector<Ring>& rings, const osmp::MemberWays& members);
|
||||||
|
|
||||||
|
void FindAllContainedRings(const std::vector<bool>& containmentMatrix, int container, int numRings, std::vector<int>& buffer);
|
||||||
|
void FindAllContainedRingsThatArentContainedByUnusedRings(const std::vector<bool>& containmentMatrix, int container, int numRings, const std::vector<Ring>& unusedRings, std::vector<int>& buffer);
|
||||||
|
[[nodiscard]] int FindUncontainedRing(const std::vector<bool>& containmentMatrix, int rings, const std::vector<Ring>& unusedRings);
|
||||||
[[nodiscard]] bool PointInsideRing(const Ring& ring, const osmp::Node& point);
|
[[nodiscard]] bool PointInsideRing(const Ring& ring, const osmp::Node& point);
|
||||||
[[nodiscard]] bool IsRingContained(const Ring& r1, const Ring& r2);
|
[[nodiscard]] bool IsRingContained(const Ring& r1, const Ring& r2);
|
||||||
[[nodiscard]] bool GroupRings(std::vector<RingGroup>& ringGroup, const std::vector<Ring>& rings);
|
[[nodiscard]] bool GroupRings(std::vector<RingGroup>& ringGroup, std::vector<Ring>& rings);
|
||||||
|
|
||||||
Multipolygon::Multipolygon(const osmp::Relation& relation, int width, int height, const osmp::Bounds& bounds) :
|
Multipolygon::Multipolygon(const osmp::Relation& relation, int width, int height, const osmp::Bounds& bounds) :
|
||||||
r(255), g(0), b(255), visible(true), rendering(RenderType::FILL), id(relation->id)
|
r(255), g(0), b(255), visible(true), rendering(RenderType::FILL), id(relation->id)
|
||||||
|
@ -63,22 +68,110 @@ Multipolygon::Multipolygon(const osmp::Relation& relation, int width, int height
|
||||||
std::cerr << "Assigning rings has failed for multipolygon " << id << std::endl;
|
std::cerr << "Assigning rings has failed for multipolygon " << id << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<RingGroup> ringGroup;
|
std::vector<RingGroup> ringGroups;
|
||||||
GroupRings(ringGroup, rings);
|
GroupRings(ringGroups, rings);
|
||||||
|
|
||||||
// TODO: Temporarily render rings:
|
char* triSwitches = "zpNBQ";
|
||||||
for (const Ring& ring : rings)
|
for (const RingGroup& ringGroup : ringGroups)
|
||||||
{
|
{
|
||||||
Polygon polygon;
|
TriangulationData td;
|
||||||
for (const osmp::Node& node : ring.nodes)
|
|
||||||
|
bool valid = true;
|
||||||
|
for (const Ring& ring : ringGroup.rings)
|
||||||
{
|
{
|
||||||
polygon.vertices.push_back({
|
std::vector<REAL> vertices;
|
||||||
Map(bounds.minlon, bounds.maxlon, 0, width, node->lon),
|
for (const osmp::Node& node : ring.nodes) {
|
||||||
height - Map(bounds.minlat, bounds.maxlat, 0, height, node->lat)
|
double x = Map(bounds.minlon, bounds.maxlon, 0, width, node->lon);
|
||||||
});
|
double y = height - Map(bounds.minlat, bounds.maxlat, 0, height, node->lat);
|
||||||
|
|
||||||
|
vertices.push_back(x);
|
||||||
|
vertices.push_back(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
int segment = td.vertices.size() / 2;
|
||||||
|
for (int i = 0; i < vertices.size() / 2; i += 1) {
|
||||||
|
td.segments.push_back(segment + i);
|
||||||
|
td.segments.push_back(segment + i + 1);
|
||||||
|
}
|
||||||
|
td.segments.back() = td.vertices.size() / 2;
|
||||||
|
|
||||||
|
td.vertices.insert(td.vertices.end(), vertices.begin(), vertices.end());
|
||||||
|
|
||||||
|
if (ring.hole) {
|
||||||
|
double holeX = 0.0f;
|
||||||
|
double holeY = 0.0f;
|
||||||
|
for (int i = 0; i < vertices.size(); i += 2)
|
||||||
|
{
|
||||||
|
holeX += vertices[i];
|
||||||
|
holeY += vertices[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
holeX /= vertices.size() / 2;
|
||||||
|
holeY /= vertices.size() / 2;
|
||||||
|
|
||||||
|
td.holes.push_back(holeX);
|
||||||
|
td.holes.push_back(holeY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
polygons.push_back(polygon);
|
// TODO: Find better way to check for duplicates
|
||||||
|
for (int i = 0; i < td.vertices.size(); i += 2) {
|
||||||
|
for (int j = 0; j < td.vertices.size(); j += 2) {
|
||||||
|
if (i == j) continue;
|
||||||
|
|
||||||
|
if (td.vertices[i] == td.vertices[j] && td.vertices[i + 1] == td.vertices[j + 1])
|
||||||
|
{
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid)
|
||||||
|
{
|
||||||
|
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.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);
|
||||||
|
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < in.numberofsegments * 2; i++) {
|
||||||
|
polygons.back().segments.push_back(in.segmentlist[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
trifree(out.trianglelist);
|
||||||
|
trifree(out.segmentlist);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make a color map
|
// TODO: Make a color map
|
||||||
|
@ -469,67 +562,67 @@ void Multipolygon::Draw(SDL_Renderer* renderer)
|
||||||
if (!visible)
|
if (!visible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (const Polygon& polygon : polygons) {
|
|
||||||
for (auto it = polygon.vertices.begin(); it != polygon.vertices.end() - 1; it++) {
|
|
||||||
thickLineRGBA(renderer,
|
|
||||||
it->x, it->y,
|
|
||||||
(it+1)->x, (it+1)->y,
|
|
||||||
2,
|
|
||||||
r, g, b, 255
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//for (const Polygon& polygon : polygons) {
|
//for (const Polygon& polygon : polygons) {
|
||||||
// switch(rendering)
|
// for (auto it = polygon.vertices.begin(); it != polygon.vertices.end() - 1; it++) {
|
||||||
// {
|
// thickLineRGBA(renderer,
|
||||||
// case RenderType::FILL:
|
// it->x, it->y,
|
||||||
// for (int i = 0; i < polygon.indices.size(); i += 3) // Be a graphics card
|
// (it+1)->x, (it+1)->y,
|
||||||
// {
|
// 2,
|
||||||
|
// r, g, b, 255
|
||||||
// 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
|
|
||||||
// );
|
// );
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case RenderType::OUTLINE:
|
|
||||||
// for(int i = 0; i < polygon.segments.size(); i += 2)
|
|
||||||
// {
|
|
||||||
// thickLineRGBA(renderer,
|
|
||||||
// polygon.vertices[polygon.segments[i + 0]].x, polygon.vertices[polygon.segments[i + 0]].y,
|
|
||||||
// polygon.vertices[polygon.segments[i + 1]].x, polygon.vertices[polygon.segments[i + 1]].y,
|
|
||||||
// 5, r, g, b, 255
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// case RenderType::INDOOR:
|
|
||||||
// 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
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for (int i = 0; i < polygon.segments.size(); i += 2)
|
|
||||||
// {
|
|
||||||
// lineRGBA(renderer,
|
|
||||||
// polygon.vertices[polygon.segments[i + 0]].x, polygon.vertices[polygon.segments[i + 0]].y,
|
|
||||||
// polygon.vertices[polygon.segments[i + 1]].x, polygon.vertices[polygon.segments[i + 1]].y,
|
|
||||||
// 10, 10, 15, 255
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
for (const Polygon& polygon : polygons) {
|
||||||
|
switch(rendering)
|
||||||
|
{
|
||||||
|
case RenderType::FILL:
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RenderType::OUTLINE:
|
||||||
|
for(int i = 0; i < polygon.segments.size(); i += 2)
|
||||||
|
{
|
||||||
|
thickLineRGBA(renderer,
|
||||||
|
polygon.vertices[polygon.segments[i + 0]].x, polygon.vertices[polygon.segments[i + 0]].y,
|
||||||
|
polygon.vertices[polygon.segments[i + 1]].x, polygon.vertices[polygon.segments[i + 1]].y,
|
||||||
|
5, r, g, b, 255
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RenderType::INDOOR:
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < polygon.segments.size(); i += 2)
|
||||||
|
{
|
||||||
|
lineRGBA(renderer,
|
||||||
|
polygon.vertices[polygon.segments[i + 0]].x, polygon.vertices[polygon.segments[i + 0]].y,
|
||||||
|
polygon.vertices[polygon.segments[i + 1]].x, polygon.vertices[polygon.segments[i + 1]].y,
|
||||||
|
10, 10, 15, 255
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Intersect(double p0_x, double p0_y, double p1_x, double p1_y, double p2_x, double p2_y, double p3_x, double p3_y)
|
bool Intersect(double p0_x, double p0_y, double p1_x, double p1_y, double p2_x, double p2_y, double p3_x, double p3_y)
|
||||||
|
@ -600,13 +693,13 @@ bool SelfIntersecting(const Ring& ring)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BuildRing(Ring& ring, osmp::MemberWays& unassigned)
|
bool BuildRing(Ring& ring, osmp::MemberWays& unassigned, int ringCount)
|
||||||
{
|
{
|
||||||
const osmp::MemberWays original = unassigned;
|
const osmp::MemberWays original = unassigned;
|
||||||
|
|
||||||
// RA-2
|
// RA-2
|
||||||
int attempts = 0;
|
int attempts = 0;
|
||||||
ring = Ring{ unassigned[attempts].way->GetNodes(), unassigned[attempts].role == "inner" };
|
ring = Ring{ unassigned[attempts].way->GetNodes(), unassigned[attempts].role == "inner", ringCount };
|
||||||
unassigned.erase(unassigned.begin() + attempts);
|
unassigned.erase(unassigned.begin() + attempts);
|
||||||
|
|
||||||
RA3:
|
RA3:
|
||||||
|
@ -620,7 +713,7 @@ RA3:
|
||||||
if (unassigned.size() == attempts)
|
if (unassigned.size() == attempts)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ring = Ring{ unassigned[attempts].way->GetNodes(), unassigned[attempts].role == "inner" };
|
ring = Ring{ unassigned[attempts].way->GetNodes(), unassigned[attempts].role == "inner", ringCount };
|
||||||
goto RA3;
|
goto RA3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -658,11 +751,14 @@ bool AssignRings(std::vector<Ring>& rings, const osmp::MemberWays& members)
|
||||||
{
|
{
|
||||||
// Ring assignment
|
// Ring assignment
|
||||||
osmp::MemberWays unassigned = members;
|
osmp::MemberWays unassigned = members;
|
||||||
|
int ringCount = 0;
|
||||||
while (!unassigned.empty())
|
while (!unassigned.empty())
|
||||||
{
|
{
|
||||||
rings.push_back({});
|
rings.push_back({});
|
||||||
if (!BuildRing(rings.back(), unassigned) || rings.size() > members.size())
|
if (!BuildRing(rings.back(), unassigned, ringCount) || rings.size() > members.size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
ringCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -673,6 +769,61 @@ bool cmp(const osmp::Node& a, const osmp::Node& b)
|
||||||
return (a->lon < b->lon);
|
return (a->lon < b->lon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FindAllContainedRings(const std::vector<bool>& containmentMatrix, int container, int numRings, std::vector<int>& buffer)
|
||||||
|
{
|
||||||
|
buffer.clear();
|
||||||
|
for (int j = 0; j < numRings; j++) {
|
||||||
|
if (containmentMatrix[INDEXOF(container, j, numRings)])
|
||||||
|
buffer.push_back(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FindAllContainedRingsThatArentContainedByUnusedRings(const std::vector<bool>& containmentMatrix, int container, int numRings, const std::vector<Ring>& unusedRings, std::vector<int>& buffer)
|
||||||
|
{
|
||||||
|
FindAllContainedRings(containmentMatrix, container, numRings, buffer);
|
||||||
|
|
||||||
|
for (auto j = buffer.begin(); j != buffer.end(); ) {
|
||||||
|
bool foundRing = false;
|
||||||
|
for (const Ring& ring : unusedRings) {
|
||||||
|
if (containmentMatrix[INDEXOF(ring.index, *j, numRings)]) {
|
||||||
|
foundRing = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(foundRing)
|
||||||
|
j = buffer.erase(j);
|
||||||
|
else
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Compare(const Ring& ring, int index) {
|
||||||
|
return (ring.index == index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FindUncontainedRing(const std::vector<bool>& containmentMatrix, int rings, const std::vector<Ring>& unusedRings)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < rings; j++) {
|
||||||
|
if (std::find_if(unusedRings.begin(), unusedRings.end(), [j](const Ring& ring) { return (ring.index == j); }) == unusedRings.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool isContained = false;
|
||||||
|
for (int i = 0; i < rings; i++) {
|
||||||
|
if (containmentMatrix[INDEXOF(i, j, rings)])
|
||||||
|
{
|
||||||
|
isContained = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isContained)
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
bool PointInsideRing(const Ring& ring, const osmp::Node& point)
|
bool PointInsideRing(const Ring& ring, const osmp::Node& point)
|
||||||
{
|
{
|
||||||
const osmp::Node& rightestNode = *(std::max_element(ring.nodes.begin(), ring.nodes.end(), cmp));
|
const osmp::Node& rightestNode = *(std::max_element(ring.nodes.begin(), ring.nodes.end(), cmp));
|
||||||
|
@ -714,8 +865,10 @@ bool IsRingContained(const Ring& r1, const Ring& r2)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GroupRings(std::vector<RingGroup>& ringGroups, const std::vector<Ring>& rings)
|
bool GroupRings(std::vector<RingGroup>& ringGroups, std::vector<Ring>& rings)
|
||||||
{
|
{
|
||||||
|
const std::vector<Ring> original = rings;
|
||||||
|
|
||||||
//RG-1
|
//RG-1
|
||||||
int ringNum = rings.size();
|
int ringNum = rings.size();
|
||||||
std::vector<bool> containmentMatrix(ringNum * ringNum);
|
std::vector<bool> containmentMatrix(ringNum * ringNum);
|
||||||
|
@ -732,7 +885,45 @@ bool GroupRings(std::vector<RingGroup>& ringGroups, const std::vector<Ring>& rin
|
||||||
containmentMatrix[INDEXOF(i, j, ringNum)] = IsRingContained(rings[i], rings[j]);
|
containmentMatrix[INDEXOF(i, j, ringNum)] = IsRingContained(rings[i], rings[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
__debugbreak();
|
|
||||||
|
// RG-2 / RG-3
|
||||||
|
while (!rings.empty()) // TODO: Make this time out
|
||||||
|
{
|
||||||
|
int uncontainedRing = FindUncontainedRing(containmentMatrix, ringNum, rings);
|
||||||
|
if (uncontainedRing == -1) {
|
||||||
|
std::cerr << "Failed to find uncontained ring in step RG-2" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto it = std::find_if(rings.begin(), rings.end(), [uncontainedRing](const Ring& ring) { return (ring.index == uncontainedRing); });
|
||||||
|
if (it == rings.end())
|
||||||
|
{
|
||||||
|
std::cerr << "Uncontained Ring is out of range" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ringGroups.push_back({ {*it} });
|
||||||
|
rings.erase(it);
|
||||||
|
|
||||||
|
|
||||||
|
// RG-4
|
||||||
|
std::vector<int> containedRings;
|
||||||
|
FindAllContainedRingsThatArentContainedByUnusedRings(containmentMatrix, uncontainedRing, ringNum, rings, containedRings);
|
||||||
|
|
||||||
|
for (auto it = rings.begin(); it != rings.end(); ) {
|
||||||
|
if (std::find(containedRings.begin(), containedRings.end(), it->index) != containedRings.end()) {
|
||||||
|
ringGroups.back().rings.push_back(*it);
|
||||||
|
ringGroups.back().rings.back().hole = true;
|
||||||
|
it = rings.erase(it);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: RG-5 / RG-6 will be left out for now as they're optional.
|
||||||
|
// At least RG-6 should be implemented because not doing so might crash Triangle
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue