Java:对多边形的顶点按逆时针方向进行排序

设多边形各顶点的坐标为:(x1, y1), (x2, y2), (x3, y3)……(xn, yn),其排列顺序是杂乱的,依次连接这n个点,无法形成确定的多边形。

对多边形的顶点按逆时针方向进行排序,可以得到凸多边形。具体步骤如下:

  • 计算多边形的内点O,以内点O作为逆时针旋转的中心点。
    多边形的内点:(Σxn/n, Σyn/n)
  • 判断点A与点B之间的方向:计算OA与OB的向量叉积,如果OA与OB的叉积大于0,则OB在OA的逆时针方向,即点A大于点B。
    向量叉积:设P=(x1, y1),Q=(x2, y2),则P×Q = x1y2 - x2y1
package Polygon;

import java.awt.*;

/**
 * 对多边形的顶点按逆时针方向进行排序
 */
public class PolygonSort {

    public static void main(String[] args) {
    
        Polygon polygon = new Polygon(new int[]{1,2,6,4,5}, new int[]{4,5,2,1,4}, 5);
        for (int i = 0; i < polygon.npoints; i++) {
            System.out.println("(" + polygon.xpoints[i] + ", " + polygon.ypoints[i] + ")");
        }
        // 对多边形的顶点按逆时针方向进行排序
        PolygonSort polygonSort = new PolygonSort();
        Polygon polygonAfterSort = polygonSort.PolygonClockwiseSort(polygon);
        System.out.println("对多边形的顶点按逆时针方向进行排序:");
        for (int i = 0; i < polygonAfterSort.npoints; i++) {
            System.out.println("(" + polygonAfterSort.xpoints[i] + ", " + polygonAfterSort.ypoints[i] + ")");
        }
    }

    /**
     * 对多边形的顶点按逆时针方向进行排序
     */
    public Polygon PolygonClockwiseSort(Polygon polygon) {
        PolygonSort polygonSort = new PolygonSort();
        // 计算多边形的内点O
        Point center = polygonSort.getCenter(polygon);
        // 冒泡排序
        Point tmp = new Point();
        for (int i = 1; i < polygon.npoints; i++) {
            for (int j = 0; j < polygon.npoints - i; j++) {
                // 判断点A与点B之间的方向
                if (PointCmp(new Point(polygon.xpoints[j], polygon.ypoints[j]), new Point(polygon.xpoints[j+1], polygon.ypoints[j+1]), center)) {
                    tmp.setLocation(polygon.xpoints[j], polygon.ypoints[j]);
                    polygon.xpoints[j] = polygon.xpoints[j+1]; polygon.ypoints[j] = polygon.ypoints[j+1];
                    polygon.xpoints[j+1] = tmp.x; polygon.ypoints[j+1] = tmp.y;
                }
            }
        }
        return polygon;
    }

    /**
     * 计算多边形的内点O
     */
    public Point getCenter(Polygon polygon) {
        // 多边形的顶点个数
        int num = polygon.npoints;
        // 多边形的顶点求和
        double X = 0, Y = 0;
        for (int i = 0; i < num; i++) {
            X += polygon.xpoints[i];
            Y += polygon.ypoints[i];
        }
        // 返回内点
        Point center = new Point();
        center.setLocation(X / num, Y / num);
        return center;
    }

    /**
     * 判断点A与点B之间的方向
     */
    public boolean PointCmp(Point pointA, Point pointB, Point center) {
        // 计算OA与OB的向量叉积
        int det = (pointA.x - center.x) * (pointB.y - center.y) - (pointB.x - center.x) * (pointA.y - center.y);
        // 若OA在OB的顺时针方向,点A大于点B,按降序排列,则返回false
        if (det > 0) {
            return false;
        }
        else {
            return true;
        }
    }
}

在这里插入图片描述


参考:

  • https://zhuanlan.zhihu.com/p/265688744
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值