Skip to content

Instantly share code, notes, and snippets.

@JamesBremner
Last active March 14, 2023 18:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JamesBremner/c30b5e812a63fd234370f719a9a568ba to your computer and use it in GitHub Desktop.
Save JamesBremner/c30b5e812a63fd234370f719a9a568ba to your computer and use it in GitHub Desktop.
Draw graph with vertices located on a 2D grid https://stackoverflow.com/q/75725261/16582
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <wex.h>
#include "cStarterGUI.h"
class cGrid2D
{
public:
typedef std::pair<int,int> point_t;
typedef std::pair<point_t,point_t> edge_t;
cGrid2D()
{
reset();
}
void reset()
{
myColCount = -1;
myRowCount = -1;
}
/// @brief Extend grid dimensions if neccessary to include point
/// @param x zero based col
/// @param y zero based row
void extDim(int x, int y)
{
if (x < 0 || y < 0)
throw std::runtime_error(
"Bad cGrid2D co-ords");
if (x > myColCount-1)
myColCount = x+1;
if (y > myRowCount-1)
myRowCount = y+1;
}
void setDim(int colCount, int rowCount)
{
myColCount = colCount;
myRowCount = rowCount;
}
void addEdge(int src, int dst)
{
vEdge.push_back(std::make_pair(src, dst));
}
void getDim(int &colCount, int &rowCount) const
{
colCount = myColCount;
rowCount = myRowCount;
}
int index(int col, int row) const
{
return row * myColCount + col;
}
void coords(int &col, int &row, int index) const
{
row = index / myColCount;
col = index - row * myColCount;
}
std::vector<std::pair<int, int>>
getPoints() const
{
std::vector<std::pair<int, int>> ret;
int x, y;
for (int p = 0; p < myColCount * myRowCount; p++)
{
coords(x, y, p);
ret.push_back(std::make_pair(x, y));
}
return ret;
}
std::vector<edge_t>
getEdges() const
{
std::vector<edge_t> ret;
for( auto& e : vEdge )
{
int x1,y1,x2,y2;
coords(x1,y1,e.first);
coords(x2,y2,e.second);
ret.push_back(
std::make_pair(
std::make_pair(x1,y1),std::make_pair(x2,y2)));
}
return ret;
}
private:
int myColCount;
int myRowCount;
std::vector<std::pair<int,int>> vEdge;
};
cGrid2D theGrid;
class cGUI : public cStarterGUI
{
public:
cGUI()
: cStarterGUI(
"Starter",
{50, 50, 1000, 500})
{
readfile("../dat/input.txt");
const int scale = 30;
const int off = 50;
fm.events().draw(
[&](PAINTSTRUCT &ps)
{
wex::shapes S(ps);
for( auto& e : theGrid.getEdges() ) {
S.line( {
scale * e.first.first + off, scale * e.first.second + off,
scale * e.second.first + off, scale * e.second.second + off});
}
for (auto &loc : theGrid.getPoints())
S.circle(
scale * loc.first + off,
scale * loc.second + off,
5);
});
show();
run();
}
private:
void readfile(const std::string &fname);
};
void cGUI::readfile(const std::string &fname)
{
std::ifstream ifs(fname);
if (!ifs.is_open())
exit(1);
theGrid.reset();
std::string line;
// 1st pass to determine extent of grid
while (getline(ifs, line))
{
int ob = -1;
while (true)
{
ob = line.find("(", ob + 1);
if (ob == -1)
break;
int x = atoi(line.substr(ob + 1).c_str());
int cm = line.find(",", ob);
int y = atoi(line.substr(cm + 1).c_str());
theGrid.extDim(x, y);
}
}
ifs.close();
ifs.open(fname);
// 2nd pass to get edges
while (getline(ifs, line))
{
int src = -1;
int ob = 0;
while (true)
{
ob = line.find("(", ob + 1);
if (ob == -1)
break;
int x = atoi(line.substr(ob + 1).c_str());
int cm = line.find(",", ob);
int y = atoi(line.substr(cm + 1).c_str());
if (src < 0)
src = theGrid.index(x, y);
else
theGrid.addEdge(src, theGrid.index(x, y));
}
}
}
main()
{
cGUI theGUI;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment