#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
struct Point {
int x, y;
Point(int x = 0, int y = 0) : x(x), y(y) {}
};
struct Line {
Point p1, p2;
Line(Point p1 = Point(), Point p2 = Point()) : p1(p1), p2(p2) {}
};
int orientation(Point p1, Point p2, Point p3) {
int val = (p2.y - p1.y) * (p3.x - p2.x) - (p2.x - p1.x) * (p3.y - p2.y);
if (val == 0) return 0;
return (val > 0) ? 1 : 2;
}
bool is_clockwise(vector<Line>& edges) {
int sum = 0;
for (int i = 0; i < edges.size(); i++) {
int j = (i + 1) % edges.size();
sum += (edges[j].p1.x - edges[i].p2.x) * (edges[j].p1.y + edges[i].p2.y);
}
return sum < 0;
}
bool find_next_edge(vector<Line>& edges, Line current_edge, vector<bool>& visited_edges, Line& next_edge) {
for (int i = 0; i < edges.size(); i++) {
if (visited_edges[i]) continue;
if (current_edge.p2.x == edges[i].p1.x && current_edge.p2.y == edges[i].p1.y) {
next_edge = edges[i];
visited_edges[i] = true;
return true;
}
else if (current_edge.p2.x == edges[i].p2.x && current_edge.p2.y == edges[i].p2.y) {
next_edge = Line(edges[i].p2, edges[i].p1);
visited_edges[i] = true;
return true;
}
}
return false;
}
vector<Line> reorder_edges(vector<Line>& edges) {
// Find a starting edge
Line current_edge = edges[0];
vector<bool> visited_edges(edges.size(), false);
visited_edges[0] = true;
vector<Line> ordered_edges;
ordered_edges.push_back(current_edge);
// Find the next edge in a clockwise direction
while (ordered_edges.size() < edges.size()) {
Line next_edge;
if (!find_next_edge(edges, current_edge, visited_edges, next_edge)) {
// If we can't find a next edge, then the edges are not connected
return vector<Line>();
}
ordered_edges.push_back(next_edge);
current_edge = next_edge;
}
// Check the orientation of the edges
if (is_clockwise(edges)) {
reverse(ordered_edges.begin(), ordered_edges.end());
}
return ordered_edges;
}
int main() {
vector<Line> edges = {
Line(Point(0, 0), Point(0, 1)),
Line(Point(0, 1), Point(1, 1)),
Line(Point(1, 1), Point(1, 0)),
Line(Point(1, 0), Point(0, 0)),
Line(Point(0, 0), Point(1, 1)),
Line(Point(0, 1), Point(1, 0))
};
vector<Line> ordered_edges = reorder_edges(edges);
if (ordered_edges.empty()) {
cout << "Edges are not connected." << endl;
return 0;
}
// Print the ordered edges
for (int i = 0; i < ordered_edges.size(); i++) {
cout << "(" << ordered_edges[i].p1.x << "," << ordered_edges[i].p1.y << ") ";
cout << "(" << ordered_edges[i].p2.x << "," << ordered_edges[i].p2.y << ")" << endl;
}
return 0;
这个算法首先从任意一条边开始,然后按顺序遍历所有的边,直到找到一条与当前边连接的下一条边。如果找不到,则说明这些边不是连通的,不能形成一个封闭的轮廓。在遍历过程中,我们还会记录遍历过的边,以确保不重复遍历。最后,我们还需要检查轮廓是按顺时针方向还是逆时针方向围成的,如果是按逆时针方向,需要反转所有的边。
在上面的代码中,`reorder_edges`函数接受一个由`Line`结构体表示的边的向量,并返回一个按正确顺序排序的边的向量。`is_clockwise`函数检查轮廓是否按逆时针方向围成,通过计算轮廓的有向面积来实现。`find_next_edge`函数找到下一个连接到给定边的边,并将其添加到已排序的边的向量中。
该算法通过从任意边开始遍历所有边,形成连通的封闭轮廓,避免重复,然后判断轮廓方向,对边进行排序。`reorder_edges`函数负责排序,`is_clockwise`检查轮廓方向,`find_next_edge`寻找相邻边。
2437

被折叠的 条评论
为什么被折叠?



