围绕中心坐标的顺序坐标 - JAVA

时间:2015-04-14 14:04:40

标签: java algorithm coordinates

在这种情况下,我正在尝试创建一个算法,该算法对一个特定点周围的坐标进行排序;中间点。

我找到了this帖子,我发现了这个回复:

- Find the center of the "circle," i.e., the average X and average Y
- Shift the X and Y values so all are relative to the new center.
- Convert to polar coordinates and sort by angle.

由于我对这种算法比较陌生,所以我决定在这里问一下。上面写的回复对我来说有点意义,但我不知道这是什么意思。

示例:

Img:click to open

如上图所示,(2,2)将是中心(绿点)。 如果一个人围绕该中心绘制一个“圆圈”,它会沿着红色方块,它会被命令如下:

(0,4) - > (2,4) - > (2,3) - > (4,3) - > (3,0) - > (1,1)

如果它会从课程的左上角开始。但是你明白了。

如果有人能指出我正确的方向和/或给我一些伪代码,我会非常感激。

谢谢!

2 个答案:

答案 0 :(得分:2)

引用的答案给出了非常高级别的描述。你实际上并不需要极坐标。特别是,您不需要点到原点的距离。您所需要的只是x轴和从原点到相应点的直线之间的角度。

根据这些角度,您可以创建Comparator,然后使用Collections#sort对点列表进行排序,并传入此比较器。

实施细节有很多自由度。但是,这里是一个MCVE,使用我在这里写的几何实用程序包中可以使用的一些方法:

import java.awt.Point;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

public class SortPointsByAngle
{
    public static void main(String[] args)
    {
        Point center = new Point(2,2);
        List<Point> points = new ArrayList<Point>();
        points.add(new Point(0, 4));
        points.add(new Point(2, 4));
        points.add(new Point(2, 3));
        points.add(new Point(4, 3));
        points.add(new Point(3, 0));
        points.add(new Point(1, 1));

        List<Point> copy = new ArrayList<Point>(points);
        Collections.shuffle(copy, new Random(0));

        System.out.println("shuffled : "+stringFor(copy));
        Collections.sort(copy, 
            Collections.reverseOrder(byAngleComparator(center)));
        System.out.println("sorted   : "+stringFor(copy));
        System.out.println("reference: "+stringFor(points));
    }

    private static String stringFor(List<Point> points)
    {
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (Point p : points)
        {
            if (!first)
            {
                sb.append(",");
            }
            first = false;
            sb.append("("+p.x+","+p.y+")");
        }
        return sb.toString();
    }

    /**
     * Creates a comparator that compares points by the angle that the line
     * between the given center and the point has to the x-axis.
     * 
     * @param center The center
     * @return The comparator
     */
    public static Comparator<Point2D> byAngleComparator(
        Point2D center)
    {
        final double centerX = center.getX();
        final double centerY = center.getY();
        return new Comparator<Point2D>()
        {
            @Override
            public int compare(Point2D p0, Point2D p1)
            {
                double angle0 = angleToX(
                    centerX, centerY, p0.getX(), p0.getY());
                double angle1 = angleToX(
                    centerX, centerY, p1.getX(), p1.getY());
                return Double.compare(angle0, angle1);
            }
        };
    }

    /**
     * Computes the angle, in radians, that the line from (x0,y0) to (x1,y1) 
     * has to the x axis
     * 
     * @param x0 The x-coordinate of the start point of the line
     * @param y0 The y-coordinate of the start point of the line
     * @param x1 The x-coordinate of the end point of the line
     * @param y1 The y-coordinate of the end point of the line
     * @return The angle, in radians, that the line has to the x-axis
     */
    private static double angleToX(
        double x0, double y0, double x1, double y1)
    {
        double dx = x1 - x0;
        double dy = y1 - y0;
        double angleRad = Math.atan2(dy, dx); 
        return angleRad;
    }
}

输出

shuffled : (3,0),(2,4),(2,3),(1,1),(4,3),(0,4)
sorted   : (0,4),(2,4),(2,3),(4,3),(3,0),(1,1)
reference: (0,4),(2,4),(2,3),(4,3),(3,0),(1,1)

答案 1 :(得分:0)

您可能希望将坐标视为矢量,并从中心点计算它们的长度。有了这些结果,您可以简单地按长度订购。