0

I have a 2-D array respresenting the x and y coordinates of a grid of points making up a rectangle. The data sets being used are typically very large. I want to sort the points starting in the top left hand corner and moving in parallel diagonal lines until the bottom right hand corner. I'm using the Arrays.sort function and the following comparator to do it:

public int compare(Object o1, Object o2) {
  double[] a1 = (double[])o1;
  double[] a2 = (double[])o2;

  if (a1[0]+a1[1] > a2[0]+a2[1]) return 1;
  else if (a1[0]+a1[1] < a2[0]+a2[1]) return -1;
  else {
    if (a1[0] > a2[0]) return 1;    
    else if (a1[0] < a2[0]) return -1;
    else return 0;
  }  
}

The code works for some reason when the x and y coordinates of each point are spaced two digits apart, but there are errors in the sort if they're spaced only one digit apart.

An example of the original order can be found here: http://www.mediafire.com/?slq73v3zn2zs98l

And an example of what the resulting sorted list is looking like can be found here: http://www.mediafire.com/?x8f08q0qoof398w

Why isn't the sort working? Any help would be so very much appreciated!

Matt Passell
  • 4,549
  • 3
  • 24
  • 39
  • 2
    Your compare function is bogus. – PEdroArthur Apr 26 '11 at 00:54
  • Use static method Double.compare(a, b), this will simplificate writting your own version of comparision method. – Lynch Apr 26 '11 at 00:57
  • Can you explain what you mean here: "I want to sort the points starting in the top left hand corner and moving in parallel diagonal lines until the bottom right hand corner."? – YXD Apr 26 '11 at 00:59
  • @Mr E Sorry to result to bad pictures and mediafire links, but I can't think to explain it otherwise. I'm trying to sort it like this: http://www.mediafire.com/i/?g6w20shw99gox0b – user990644 Apr 26 '11 at 01:04
  • @PEdroArthur What should I change to make it less bogusserrific? – user990644 Apr 26 '11 at 01:05

1 Answers1

0

Looking at the picture you have linked to, I think you want to do Double.compare() on the L1 distance of the point from the top left corner.

This means, given 2d points a and b, and "origin" Origin (in this case the top-left point) you want to compare:

distance_a = Math.abs(Origin.x - a.x) + Math.abs(Origin.y - a.y)
distance_b = Math.abs(Origin.x - b.x) + Math.abs(Origin.y - b.y)
return Double.compare(distance_a,distance_b);

and sort by comparing these distances. You could wrap this up into a sensible comparator that uses Double.compare().

Update: I understand the extra sorting criteria now, after your last comment. You may want to consider precision issues when comparing doubles (someone else will be able to advise you better), however you want something roughly like:

distance_a = Math.abs(Origin.x - a.x) + Math.abs(Origin.y - a.y)
distance_b = Math.abs(Origin.x - b.x) + Math.abs(Origin.y - b.y)
if distance_a is not equal to distance_b // check how you should perform the comparison
    return Double.compare(distance_a,distance_b);
else
    return Double.compare(a.x,b.x);
Community
  • 1
  • 1
YXD
  • 31,741
  • 15
  • 75
  • 115
  • This is what I have written already in these lines: if(a1[0]+a1[1] > a2[0]+a2[1]) return 1; else if(a1[0]+a1[1] < a2[0]+a2[1]) return -1; where a1 and a2 are the points, a1[0] and a1[1] are the x and y of a1 respectively. Why does the function Double.compare() need to be used? Doesn't the > sign compare them? – user990644 Apr 26 '11 at 01:32
  • 1. You need to sum the absolute values., which you're not doing 2. Assuming that's fixed your code is only valid if the top left point of the box is at (0,0) – YXD Apr 26 '11 at 01:35
  • The top left point is always 0,0 so thats not a problem. It seems like it sorts everything according to the L1 distance correctly, just not in descending x order where points have the same L1 distance. for example, the sorted list has points in this order: (0.7 0.6) (0.6 0.7) (1.3 0.0) (1.2 0.1) (1.1 0.2) (1.0 0.3) (0.9 0.4) (0.8 0.5) (0.5 0.8) (0.4 0.9) (0.3 1.0) (0.2 1.1) (0.1 1.2) (0.0 1.3) – user990644 Apr 26 '11 at 01:47
  • Thanks so much! You were right, it was a precision problem when comparing the double values. I really appreciate the help. – user990644 Apr 26 '11 at 12:59