#include "pch.h"
#include "ArrangementFunctions.h"
#include "Convex_expansion_visibility_2_temp.h"
#include "IOHandling.h"
#include "IPSolver.h"
#include "simpleSVG.hpp"
typedef Convex_expansion_visibility_2 CEV;
static double dimensionX = 1450;
static double dimensionY = 850;
svg::Dimensions dimensions;
static double minX = INT_MAX;
static double minY = INT_MAX;
static double maxX = -INT_MAX;
static double maxY = -INT_MAX;
/// Reads an input polygon from .pol file
/// Name of file (randsimple, ortho, etc...)
/// Size of the polygon
/// ID of the polygon
/// Polygon in terms of a vector of its points
std::vector readPoly(std::string name, int n, int num) {
std::string filename = std::string("c:\\dev\\poly\\" + name + "\\" + name + "-" + std::to_string(n) + "-" + std::to_string(num) + ".pol");
std::vector poly = {};
std::ifstream inFile;
inFile.open(filename);
std::string str;
std::getline(inFile, str);
std::istringstream iss(str);
std::vector results(std::istream_iterator{iss},
std::istream_iterator());
std::string delimiter = "/";
for (int i = 1; i < results.size(); i = i + 2) {
double num1, div1;
double num2, div2;
int findpos1 = results[i].find(delimiter);
int findpos2 = results[i + 1].find(delimiter);
num1 = std::stod(results[i].substr(0, findpos1));
div1 = std::stod(results[i].substr(findpos1 + 1, results[i].length() - 1 - findpos1));
num2 = std::stod(results[i + 1].substr(0, findpos2));
div2 = std::stod(results[i + 1].substr(findpos2 + 1, results[i + 1].length() - 1 - findpos2));
poly.push_back(Point_2(num1 / div1, num2 / div2));
}
/*poly = {Point_2(1,1), Point_2(2, 1), Point_2(2,2)};
Polygon_2 pol(poly.begin(), poly.end());
CGAL::Orientation or = pol.orientation();
std::reverse(poly.begin(), poly.end());*/
return poly;
}
void IOHandling::GetTestPolygon(int polygonID, int size, bool inTestMode, Arrangement_2& arr) {
if(inTestMode)
polygonToArrangement(readPoly("randsimple", size, polygonID), arr);
else
polygonToArrangement(testPolygons[polygonID], arr);
}
vector> IOHandling::testPolygons = {
//p1
{ Point_2(1,1), Point_2(55,1), Point_2(60,20), Point_2(40,30), Point_2(65,50), Point_2(55,80), Point_2(5,80), Point_2(15,65),
Point_2(10,50), Point_2(36,43), Point_2(30,37), Point_2(10,30), Point_2(15, 10) },
//p2
{ Point_2(9,11), Point_2(67,11), Point_2(61,1), Point_2(75,9), Point_2(77,15), Point_2(67,25), Point_2(51,25),
Point_2(39,35), Point_2(75,35), Point_2(73,47), Point_2(77,55), Point_2(71,57), Point_2(69,51), Point_2(15,51), Point_2(5, 45),
Point_2(17,47), Point_2(37,41), Point_2(29,47), Point_2(21,47), Point_2(19,50), Point_2(29,48), Point_2(47,46), Point_2(16, 25),
Point_2(1, 35), Point_2(1, 1) },
//p3
{ Point_2(1,27), Point_2(50,27), Point_2(75,1), Point_2(75,51), Point_2(25,51), Point_2(10,76) },
//p4
{ Point_2(-2,55), Point_2(1,50), Point_2(1,1), Point_2(75,1), Point_2(75,50), Point_2(70,60), Point_2(65,50), Point_2(60,60),
Point_2(55,50), Point_2(25,50), Point_2(20,60), Point_2(15,50) },
//p5
{
Point_2(0,-12,19),
Point_2(2 * 19,-12, 19), Point_2(2,0), //first nook
Point_2(3,0), Point_2(3,-0.15), Point_2(3.5,0), //second nook
Point_2(4,0), Point_2(4 * 19,-12,19), Point_2(8 * 19,-18,19), Point_2(8,0), //first bottom rectangle
Point_2(12,0), Point_2(12 * 21,-34,21), Point_2(16 * 21,-36,21), Point_2(16,0), //second bottom rectangle
//Point_2(18.9,0), Point_2(19,-0.5), Point_2(19,0), //third bottom book
Point_2(20,0), //Point_2(20,0.5), Point_2(30,0.5), Point_2(30,0.6), Point_2(20,0.6), //right tube
Point_2(20 * 375 ,1776, 375), Point_2(19 * 375, 1776, 375), Point_2(19,4), //first top nook
Point_2(17 * 6 + 2,4 * 6, 6), Point_2(17 * 6 + 2,4.15 * 6, 6), Point_2(16 * 6 + 5 ,4 * 6, 6), //second top nook
Point_2(16,4), Point_2(16 * 375 ,1776, 375), Point_2(12 * 375,2486, 375), Point_2(12,4), //first top rectangle
//Point_2(10.6,4), Point_2(10.6,8), Point_2(10.5,8), Point_2(10.5,4), //top tube
Point_2(8,4), Point_2(8 * 47,294,47), Point_2(4 * 47,280,47), Point_2(4,4), //second top rectangle
//Point_2(2.1,4), Point_2(2,4.5), Point_2(2,4), //third top nook
Point_2(0,4), //Point_2(0,1.8), Point_2(-10,1.8), Point_2(-10,1.7), //left tube
//Point_2(0,1.7)
},
//P6 - false positive witness test
{
Point_2(0,0), Point_2(10,0), Point_2(10,11.5), Point_2(15,11.5), Point_2(15,12.5), Point_2(10,12.5), Point_2(10,15), Point_2(30,15),
Point_2(30,12.5), Point_2(25,12.5), Point_2(25,11.5), Point_2(30,11.5), Point_2(30,0), Point_2(40,0), Point_2(40,20), Point_2(0,20)
},
//P7 - weakvis interesction test
{
Point_2(0,0), Point_2(50,0), Point_2(30,10), Point_2(45,20), Point_2(27, 35), Point_2(45, 65), Point_2(5, 65), Point_2(23, 35),
Point_2(5, 20), Point_2(20,10)
}
};
svg::Point scalePoint(Point_2 cgalPoint) {
double xScale = dimensionX / (maxX - minX);
double yScale = dimensionY / (maxY - minY);
double finalScale = min(xScale, yScale) * 0.9;
return svg::Point(
20 + finalScale * (CGAL::to_double(cgalPoint.x()) + (-1 * minX)),
20 + finalScale * (CGAL::to_double(cgalPoint.y()) + (-1 * minY))
);
}
svg::Polygon FillFace(Face_handle f, svg::Color stroke, svg::Color fill) {
svg::Polygon face(svg::Fill(fill), svg::Stroke(1.5, stroke));
auto eit = f->outer_ccb();
do {
face << scalePoint(eit->source()->point());
} while (++eit != f->outer_ccb());
return face;
}
void DrawBoundary(Arrangement_2 &theArrangement, svg::Document& doc) {
svg::Polygon outline(svg::Stroke(1.5, svg::Color::Black));
Arrangement_2::Ccb_halfedge_circulator eit = *theArrangement.unbounded_face()->inner_ccbs_begin();
do {
outline << scalePoint(eit->source()->point());
} while (++eit != *(theArrangement.unbounded_face()->inner_ccbs_begin()));
doc << outline;
}
void IOHandling::DrawPolygon(vector polygon, string fileLocation) {
svg::Document doc("output/" + fileLocation + ".svg", svg::Layout(dimensions, svg::Layout::BottomLeft));
svg::Polygon outline(svg::Stroke(1.5, svg::Color::Black));
for(auto it = polygon.begin(); it != polygon.end(); it++)
outline << scalePoint(*it);
doc << outline;
doc.save();
}
void IOHandling::SetDimensions(Arrangement_2& theArrangement) {
minX = minY = INT_MAX;
maxX = maxY = -INT_MAX;
//Find minima and maxima of arrangement
for (Arrangement_2::Halfedge_handle eit = theArrangement.halfedges_begin(); eit != theArrangement.halfedges_end(); ++eit) {
double x = CGAL::to_double(eit->source()->point().x());
double y = CGAL::to_double(eit->source()->point().y());
if (x < minX)
minX = x;
if (y < minY)
minY = y;
if (x > maxX)
maxX = x;
if (y > maxY)
maxY = y;
}
dimensions = svg::Dimensions(dimensionX, dimensionY);
}
bool IOHandling::DrawDecomposition(Arrangement_2 &theArrangement, shared_ptr& weakVisRoot, string fileLocation) {
svg::Dimensions dimensions(dimensionX, dimensionY);
svg::Document doc("output/" + fileLocation + ".svg", svg::Layout(dimensions, svg::Layout::BottomLeft));
//iterate through weak vis decomposition and draw
stack> nodeStack;
stack colourStack;
nodeStack.push(weakVisRoot);
colourStack.push(true);
//Iterate over weakvisdecomp
while (!nodeStack.empty())
{
shared_ptr currentNode = nodeStack.top();
bool currentColour = colourStack.top();
nodeStack.pop();
colourStack.pop();
svg::Color fillColour = svg::Color::Green;
if (!currentColour)
fillColour = svg::Color::Lime;
svg::Polygon decompPolygon(svg::Fill(fillColour), svg::Stroke(1.5, svg::Color::Orange));
//Draw things
//segments orange
Arrangement_2::Ccb_halfedge_circulator eit = *currentNode->ownPolygon.unbounded_face()->inner_ccbs_begin();
do {
decompPolygon << scalePoint(eit->source()->point());
} while (++eit != *(currentNode->ownPolygon.unbounded_face()->inner_ccbs_begin()));
doc << decompPolygon;
//Add children to stack
for (auto it = currentNode->children.begin(); it != currentNode->children.end(); ++it) {
nodeStack.push(shared_ptr(*it));
colourStack.push(!currentColour); //children are opposite colour
}
}
DrawBoundary(theArrangement, doc);
return doc.save();
}
bool IOHandling::DrawArtGallery(Arrangement_2 &theArrangement, string fileLocation, IPSolver IP) {
svg::Document doc("output/" + fileLocation + ".svg", svg::Layout(dimensions, svg::Layout::BottomLeft));
for (auto it = IP.unseenFaces.begin(); it != IP.unseenFaces.end(); ++it)
doc << FillFace(*it, svg::Color::Lime, svg::Color::Lime); //lime facewitnesses
for (auto it = IP.faceSolution.begin(); it != IP.faceSolution.end(); ++it)
doc << FillFace(*it, svg::Color::Orange, svg::Color::Orange); //orange faceguards
//inner segments gray
for (auto eit = theArrangement.edges_begin(); eit != theArrangement.edges_end(); ++eit) {
svg::Line innerSegment(scalePoint(eit->source()->point()), scalePoint(eit->target()->point()),
svg::Stroke(1, svg::Color::Gray));
doc << innerSegment;
}
DrawBoundary(theArrangement, doc);
for (auto it = IP.unseenFaces.begin(); it != IP.unseenFaces.end(); ++it) {
auto eit = (*it)->outer_ccb();
doc << svg::Elipse(scalePoint(eit->source()->point()), 8, 8, svg::Color::Lime, svg::Stroke(1, svg::Color::Black));
}
for (auto it = IP.faceSolution.begin(); it != IP.faceSolution.end(); ++it) {
auto eit = (*it)->outer_ccb();
doc << svg::Elipse(scalePoint(eit->source()->point()), 8, 8, svg::Color::Orange, svg::Stroke(1, svg::Color::Black));
}
for (auto it = IP.vertexSolution.begin(); it != IP.vertexSolution.end(); ++it)
doc << svg::Elipse(scalePoint((*it)->point()), 25, 25, svg::Color::Orange, svg::Stroke(1, svg::Color::Black));
return doc.save();
}
bool IOHandling::DrawCritical(Arrangement_2 &theArrangement, string fileLocation) {
svg::Document doc("output/" + fileLocation + ".svg", svg::Layout(dimensions, svg::Layout::BottomLeft));
for (auto fit = theArrangement.faces_begin(); fit != theArrangement.faces_end(); ++fit)
if(fit->data().isCritical)
doc << FillFace(fit, svg::Color::Green, svg::Color::Green);
//inner segments gray
for (auto eit = theArrangement.edges_begin(); eit != theArrangement.edges_end(); ++eit) {
svg::Line innerSegment(scalePoint(eit->source()->point()), scalePoint(eit->target()->point()),
svg::Stroke(0.4, svg::Color::Silver));
doc << innerSegment;
}
DrawBoundary(theArrangement, doc);
for (auto vit = theArrangement.vertices_begin(); vit != theArrangement.vertices_end(); ++vit)
if (vit->data().isCritical)
doc << svg::Elipse(scalePoint((vit)->point()), 25, 25, svg::Color::Green, svg::Stroke(1, svg::Color::Black));
return doc.save();
}
bool IOHandling::DrawWeakVis(CEV& weakVisibility, string fileLocation, vector testFace, list weakVis, int step) {
svg::Document doc("output/" + fileLocation + ".svg", svg::Layout(dimensions, svg::Layout::BottomLeft));
if (step > -1)
weakVis = weakVisibility.vis_polygons[step];
//Draw visibility polygon
svg::Polygon visPoly(svg::Fill(svg::Color::Lime), svg::Stroke(1, svg::Color::Lime));
for (auto pit = weakVis.begin(); pit != weakVis.end(); pit++) {
visPoly << scalePoint(*pit);
}
doc << visPoly;
//Draw f0_boundary
if (weakVisibility.f0_boundary.size() > 0)
{
svg::Polygon boundaryPoly(svg::Fill(svg::Color::Green), svg::Stroke(1, svg::Color::Green));
for (auto pit = weakVisibility.f0_boundary.begin(); pit != weakVisibility.f0_boundary.end(); pit++)
boundaryPoly << scalePoint(*pit);
doc << boundaryPoly;
}
if (step > -1) {
Segment_2 alphaTangent = weakVisibility.saved_a_tangents[step];
Segment_2 betaTangent = weakVisibility.saved_b_tangents[step];
Segment_2 firstAlphaTangent = weakVisibility.saved_first_a_tangents[step];
Segment_2 firstBetaTangent = weakVisibility.saved_first_b_tangents[step];
for(auto pit = weakVisibility.saved_alpha_blockers[step].begin(); pit != weakVisibility.saved_alpha_blockers[step].end(); pit++)
doc << svg::Elipse(scalePoint(*pit), 25, 25, svg::Color::Red, svg::Stroke(1, svg::Color::Black));
for (auto pit = weakVisibility.saved_beta_blockers[step].begin(); pit != weakVisibility.saved_beta_blockers[step].end(); pit++)
doc << svg::Elipse(scalePoint(*pit), 25, 25, svg::Color::Blue, svg::Stroke(1, svg::Color::Black));
svg::Polyline alphaLine(svg::Stroke(1.5, svg::Color::Red));
alphaLine << scalePoint(alphaTangent.source());
alphaLine << scalePoint(alphaTangent.target());
doc << alphaLine;
svg::Polyline betaLine(svg::Stroke(1.5, svg::Color::Blue));
betaLine << scalePoint(betaTangent.source());
betaLine << scalePoint(betaTangent.target());
doc << betaLine;
svg::Polyline FirstAlphaLine(svg::Stroke(1.5, svg::Color::Silver));
FirstAlphaLine << scalePoint(firstAlphaTangent.source());
FirstAlphaLine << scalePoint(firstAlphaTangent.target());
doc << FirstAlphaLine;
svg::Polyline firstBetaLine(svg::Stroke(1.5, svg::Color::Silver));
firstBetaLine << scalePoint(firstBetaTangent.source());
firstBetaLine << scalePoint(firstBetaTangent.target());
doc << firstBetaLine;
}
//Draw test face
svg::Polygon testFacePoly(svg::Fill(svg::Color::Orange), svg::Stroke(5, svg::Color::Orange));
for (auto sit = testFace.begin(); sit != testFace.end(); sit++) {
if (sit == testFace.begin())
{
doc << svg::Elipse(scalePoint(sit->source()), 25, 25, svg::Color::Black, svg::Stroke(1, svg::Color::Black));
doc << svg::Elipse(scalePoint(sit->target()), 25, 25, svg::Color::White, svg::Stroke(1, svg::Color::Black));
}
testFacePoly << scalePoint(sit->source());
}
doc << testFacePoly;
//inner segments gray
for (auto eit = weakVisibility.convex_partition.edges_begin(); eit != weakVisibility.convex_partition.edges_end(); ++eit) {
svg::Line innerSegment(scalePoint(eit->source()->point()), scalePoint(eit->target()->point()),
svg::Stroke(0.4, svg::Color::Silver));
doc << innerSegment;
}
DrawBoundary(weakVisibility.convex_partition, doc);
for (auto pit = weakVis.begin(); pit != weakVis.end(); pit++) {
doc << svg::Elipse(scalePoint(*pit), 5, 5, svg::Color::Lime, svg::Stroke(1, svg::Color::Black));
}
return doc.save();
}
chrono::steady_clock::time_point IOHandling::get_cpu_time() {
//FILETIME a, b, c, d;
//if (GetProcessTimes(GetCurrentProcess(), &a, &b, &c, &d) != 0) {
// // Returns total user time.
// // Can be tweaked to include kernel times as well.
// return
// (double)(d.dwLowDateTime |
// ((unsigned long long)d.dwHighDateTime << 32)) * 0.0000001;
//}
//else {
// // Handle error
// return 0;
//}
return std::chrono::high_resolution_clock::now();
}