Added initial path implementation. Needs stroke width fixing
This commit is contained in:
parent
4d46780e2a
commit
da743e0e16
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@ polygon
|
||||
polygon.exe
|
||||
path
|
||||
path.exe
|
||||
.vscode/*
|
||||
|
||||
177
main_path.cpp
Normal file
177
main_path.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct Point
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
|
||||
Point& operator/=(const double& val)
|
||||
{
|
||||
x /= val;
|
||||
y /= val;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
Point operator-(const Point& p1, const Point& p2)
|
||||
{
|
||||
return Point{.x = p1.x - p2.x, .y = p1.y - p2.y};
|
||||
}
|
||||
|
||||
Point operator+(const Point& p1, const Point& p2)
|
||||
{
|
||||
return Point{.x = p1.x + p2.x, .y = p1.y + p2.y};
|
||||
}
|
||||
|
||||
double radians(double degrees)
|
||||
{
|
||||
return degrees * M_PI / 180.0;
|
||||
}
|
||||
|
||||
double degrees(double radians)
|
||||
{
|
||||
return radians * 180.0 / M_PI;
|
||||
}
|
||||
|
||||
Point& vec_normalize(Point& vec)
|
||||
{
|
||||
double len = sqrt(vec.x * vec.x + vec.y * vec.y);
|
||||
vec /= len;
|
||||
return vec;
|
||||
}
|
||||
|
||||
double get_angle(Point start, Point end)
|
||||
{
|
||||
double angle;
|
||||
Point vec;
|
||||
double dot;
|
||||
|
||||
vec = end - start;
|
||||
vec_normalize(vec);
|
||||
|
||||
angle = degrees(acos(vec.x));
|
||||
|
||||
if (vec.y < 0)
|
||||
{
|
||||
angle += 180.0;
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
double get_stroke_angle(double prev_angle, double curr_angle)
|
||||
{
|
||||
double angle;
|
||||
|
||||
angle = (curr_angle - prev_angle) / 2 + prev_angle + 90;
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
pair<Point, Point> perform_stroke(double stroke_size, double stroke_angle, Point point)
|
||||
{
|
||||
pair<Point, Point> result;
|
||||
Point add;
|
||||
|
||||
add.x = cos(radians(stroke_angle)) * stroke_size / 2;
|
||||
add.y = sin(radians(stroke_angle)) * stroke_size / 2;
|
||||
|
||||
result.first = point + add;
|
||||
result.second = point - add;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void usage(const string& name)
|
||||
{
|
||||
cout << "Usage: " << name << "<stroke size> <x1> <y1> <x2> <y2> [<xN> <yN> ...]" << endl;
|
||||
cout << "\tstroke size - how big the stroke should be" << endl;
|
||||
cout << "\tx1 - x coordinate of first point" << endl;
|
||||
cout << "\ty1 - y coordinate of first point" << endl;
|
||||
}
|
||||
|
||||
void get_polygon(double stroke_size, const vector<Point>& points)
|
||||
{
|
||||
double prev_angle;
|
||||
double curr_angle;
|
||||
vector<Point> forward;
|
||||
vector<Point> backward;
|
||||
pair<Point, Point> tmp;
|
||||
|
||||
for (int i = 1; i < points.size(); ++i)
|
||||
{
|
||||
prev_angle = curr_angle;
|
||||
curr_angle = get_angle(points[i - 1], points[i]);
|
||||
|
||||
if (1 == i)
|
||||
{
|
||||
// First angle is end cap
|
||||
tmp = perform_stroke(stroke_size, curr_angle + 90, points[i - 1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = perform_stroke(stroke_size, get_stroke_angle(prev_angle, curr_angle), points[i - 1]);
|
||||
}
|
||||
|
||||
forward.push_back(tmp.first);
|
||||
backward.push_back(tmp.second);
|
||||
}
|
||||
|
||||
// Last angle is end cap
|
||||
tmp = perform_stroke(stroke_size, curr_angle + 90, points[points.size() - 1]);
|
||||
forward.push_back(tmp.first);
|
||||
backward.push_back(tmp.second);
|
||||
|
||||
for (int i = 0; i < forward.size(); ++i)
|
||||
{
|
||||
cout << forward[i].x << "," << forward[i].y << " ";
|
||||
}
|
||||
|
||||
for (int i = backward.size() - 1; i >= 0; --i)
|
||||
{
|
||||
cout << backward[i].x << "," << backward[i].y << " ";
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
double stroke_size;
|
||||
Point tmp;
|
||||
vector<Point> points;
|
||||
int last_idx;
|
||||
|
||||
if (argc < 5)
|
||||
{
|
||||
usage(argv[0]);
|
||||
cout << "Insufficient arguments" << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
stroke_size = stod(argv[1]);
|
||||
|
||||
last_idx = argc;
|
||||
if (0 != last_idx % 2)
|
||||
{
|
||||
--last_idx;
|
||||
}
|
||||
|
||||
for (int i = 2; i < last_idx; i += 2)
|
||||
{
|
||||
tmp.x = stod(argv[i]);
|
||||
tmp.y = stod(argv[i + 1]);
|
||||
points.push_back(tmp);
|
||||
}
|
||||
|
||||
get_polygon(stroke_size, points);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user