线段排序算法-C++

该算法通过从任意边开始遍历所有边,形成连通的封闭轮廓,避免重复,然后判断轮廓方向,对边进行排序。`reorder_edges`函数负责排序,`is_clockwise`检查轮廓方向,`find_next_edge`寻找相邻边。
#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`函数找到下一个连接到给定边的边,并将其添加到已排序的边的向量中。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时间简史u

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值