计算笛卡尔(二维)坐标系的数值索引

时间:2015-04-03 09:13:57

标签: java math coordinates coordinate-systems

给出笛卡尔(二维)坐标系,如下所示:

kartesian coordinate system

是否有可能 - 如果,如何 - 为每个字段计算唯一的可排序索引?这意味着,使用x和y坐标,我想计算从左到右,从上到下递增的索引号。 E.g:

unique numeric indexes

(仅)必须满足以下条件:

  • 索引号必须是唯一的(即使对于较大的系统)
  • 数字必须从左到右,从上到下递增(但不一定是连续的)
  • 必须是正整数,正整数值
  • 必须在Java中实现

我发现了什么:加法,乘法和幂(例如x * y或x ^ y)不起作用,因为不同的字段获得相同的索引。

Method Body可能如下所示:

public Integer getIndex(Integer xCoordinate, Integer yCoordinate) {
  // ...
}

BTW:坐标总是正的(0 <= x

感谢您的任何建议。

解:

我在没有计算索引的情况下解决了问题,并使用了Teepeemm提出的简单比较(见评论)

2 个答案:

答案 0 :(得分:4)

基于你的例子的明显答案是使用:

index = (#cols * row + col)

但这取决于事先知道列数,并且它足够小以至于你没有溢出。

另一种方法是沿对角线索引:

index = ((row + col) * (row + col + 1))/2 + row

所以你的索引看起来像:

  0   2   5   9
  1   4   8  13
  3   7  12  18
  6  11  17  24

顺便说一句,因为你在做算术,你最好使用原始int而不是盒装Integer来避免创建不必要的Integer对象(Effective Java 2nd ed Item 5)

答案 1 :(得分:1)

answer by Andy Turner实际上包含了您需要的所有内容。根据您的评论,您不知道列数。在这种情况下,你必须假设最坏的情况:如果你不知道是否有少于64k列和少于64k行,那么你甚至不知道是否有足够的int s代表不同的指数。

所以一个解决方案(即#34;尽可能通用&#34;,给定这些未知数)是将y - 值乘以列数而不是最大值可以合理计算索引的列数。如果你知道行的最大数量,那么你可以在这里选择一个合适的数字,但是如果你没有,那么你必须乘以65536 - 这可以作为左边 - 移位16位。 (如果需要,请考虑这里的符号位。)

结果可能是

Shuffled: [(1,0), (2,1), (2,2), (0,2), (2,0), (1,1), (1,2), (0,0), (0,1)]
Sorted  : [(0,0), (1,0), (2,0), (0,1), (1,1), (2,1), (0,2), (1,2), (2,2)]
Indices:
      0       1       2 
  65536   65537   65538 
 131072  131073  131074 

以下是一个示例实现:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class AscendingIndices
{
    public static void main(String[] args)
    {
        List<Coordinate> coordinates = new ArrayList<Coordinate>();
        for (int x=0; x<3; x++)
        {
            for (int y=0; y<3; y++)
            {
                coordinates.add(new Coordinate(x,y));
            }
        }
        Collections.shuffle(coordinates);
        System.out.println("Shuffled: "+coordinates);        
        Collections.sort(coordinates);
        System.out.println("Sorted  : "+coordinates);

        System.out.println("Indices:");
        for (int y=0; y<3; y++)
        {
            for (int x=0; x<3; x++)
            {
                Coordinate c = new Coordinate(x,y);
                System.out.printf("%7d ", c.getIndex());
            }
            System.out.printf("\n");
        }

   }
}

class Coordinate implements Comparable<Coordinate>
{
    private final int x;
    private final int y;

    Coordinate(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    int getIndex()
    {
        return x + (y << 16);
    }


    @Override
    public String toString()
    {
        return "("+x+","+y+")";
    }

    @Override
    public int compareTo(Coordinate o)
    {
        return Integer.compare(getIndex(), o.getIndex());
    }

}