Sort a PVector Array

i'm using the Delauney Filter code and want to extract the cordinates from the array in order from low to high.

Sort(); isn't working for me. Presumably a basic syntax error. But i can't see it, and i've searched here for similiar answers but to no success. Help welcomed:

import java.util.List;
import java.util.LinkedList;

int W = 800, H = 800;
int[] colors;
ArrayList<Triangle> triangles;

PFont myFont;


void setup() 
{
  size(800, 800);
  smooth();

  myFont = createFont("Arial", 10);
  textFont(myFont);
  textAlign(CENTER, CENTER);
  noFill();



  //Portrait of Jean-Charles de Cordes, by Rubens
  PImage buffer = loadImage("r.jpg");

  //Extract significant points of the picture
  ArrayList<PVector> vertices = new ArrayList<PVector>();

  //last number sets resolution - higher = fewer triangles
  EdgeDetector.extractPoints(vertices, buffer, EdgeDetector.SOBEL, 300, 100);

  //Add some points in the border of the canvas to complete all space
  for (float i = 0, h = 0, v = 0; i<=1; i+=.05, h = W*i, v = H*i) {
    vertices.add(new PVector(h, 0));
    vertices.add(new PVector(h, H));
    vertices.add(new PVector(0, v));
    vertices.add(new PVector(W, v));
  }

  //Get the triangles using qhull algorithm. 
  //The algorithm is a custom refactoring of Triangulate library by Florian Jennet (a port of Paul Bourke... not surprisingly... :D) 
  triangles = new ArrayList<Triangle>();
  new Triangulator().triangulate(vertices, triangles);

  //Prune triangles with vertices outside of the canvas.
  Triangle t = new Triangle();
  for (int i=0; i < triangles.size(); i++) {
    t = triangles.get(i); 
    if (vertexOutside(t.p1) || vertexOutside(t.p2) || vertexOutside(t.p3)) triangles.remove(i);
  }

  //Get colors from the triangle centers
  int tSize = triangles.size();
  colors = new int[tSize*3];
  PVector c = new PVector();
  for (int i = 0; i < tSize; i++) {
    c = triangles.get(i).center();
    colors[i] = buffer.get(int(c.x), int(c.y));
  }

  //And display the result
  displayMesh();
}

//Util function to prune triangles with vertices out of bounds  
boolean vertexOutside(PVector v) { 
  return v.x < 0 || v.x > width || v.y < 0 || v.y > height;
}  

/**
  An algorithm that uses a custom implementation of a Sobel/Scharr operator to get the significant points of a picture.
*/

static class EdgeDetector
{
    static final int [][][] OPERATOR  = new int[][][]  {
        { {2,  2, 0}, { 2, 0,  -2}, {0,  -2, -2}},  //Sobel kernel
        { {6, 10, 0}, {10, 0, -10}, {0, -10, -6}}   //Scharr kernel
    };
    static final int SOBEL = 0, SCHARR = 1;  //Indexes of the kernels in the previous array

    //This method add significant points of the given picture to a given list
    static void extractPoints(List <PVector> vertices, PImage img, int op, int treshold, int res) 
    {     
          int col = 0, colSum = 0, W = img.width-1, H = img.height-1;

          //For any pixel in the image excepting borders            
          for (int Y = 1; Y < H; Y += res) for (int X = 1; X < W; X += res, colSum = 0) 
          {
              //Convolute surrounding pixels with desired operator       
              for (int y = -1; y <= 1; y++) for (int x = -1; x <= 1; x++, col = img.get((X+x), (Y+y))) 
                  colSum += OPERATOR[op][x+1][y+1] * ((col>>16 & 0xFF)+(col>>8 & 0xFF)+(col & 0xFF));               
              //And if the resulting sum is over the treshold add pixel position to the list
              if (abs(colSum) > treshold) vertices.add(new PVector(X, Y));                                  
          }  
     }    
}    

/** 
  A custom refactoring of Triangulate library by Florian Jennet
  Only minor changes to adapt it to my coding tastes. Not much interesting for anyone else, I think. : )
*/ 

import java.util.Comparator;
import java.util.Collections;
import java.util.Arrays;
import java.util.HashSet;

/**
    CircumCircle
    Calculates if a point (xp,yp) is inside the circumcircle made up of the points (x1,y1), (x2,y2), (x3,y3)
    The circumcircle centre is returned in (xc,yc) and the radius r. A point on the edge is inside the circumcircle
*/

public static class CircumCircle 
{ 
    public static boolean circumCircle(PVector p, Triangle t, PVector circle) 
    {
        float m1, m2, mx1, mx2, my1, my2;
        float dx, dy, rsqr, drsqr;

        /** Check for coincident points */
        if (abs(t.p1.y-t.p2.y) < EPSILON && abs(t.p2.y-t.p3.y) < EPSILON) {
          //println("CircumCircle: Points are coincident.");
          return false;
        }

        if (abs(t.p2.y-t.p1.y) < EPSILON) {
          m2 = - (t.p3.x-t.p2.x) / (t.p3.y-t.p2.y);
          mx2 = (t.p2.x + t.p3.x) * .5;
          my2 = (t.p2.y + t.p3.y) * .5;
          circle.x = (t.p2.x + t.p1.x) * .5;
          circle.y = m2 * (circle.x - mx2) + my2;
        }
        else if (abs(t.p3.y-t.p2.y) < EPSILON) {
          m1 = - (t.p2.x-t.p1.x) / (t.p2.y-t.p1.y);
          mx1 = (t.p1.x + t.p2.x) * .5;
          my1 = (t.p1.y + t.p2.y) * .5;
          circle.x = (t.p3.x + t.p2.x) *.5;
          circle.y = m1 * (circle.x - mx1) + my1;  
        }
        else {
          m1 = - (t.p2.x-t.p1.x) / (t.p2.y-t.p1.y);
          m2 = - (t.p3.x-t.p2.x) / (t.p3.y-t.p2.y);
          mx1 = (t.p1.x + t.p2.x) * .5;
          mx2 = (t.p2.x + t.p3.x) * .5;
          my1 = (t.p1.y + t.p2.y) * .5;
          my2 = (t.p2.y + t.p3.y) * .5;
          circle.x = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2);
          circle.y = m1 * (circle.x - mx1) + my1;
        }

        dx = t.p2.x - circle.x;
        dy = t.p2.y - circle.y;
        rsqr = dx*dx + dy*dy;
        circle.z = sqrt(rsqr);

        dx = p.x - circle.x;
        dy = p.y - circle.y;
        drsqr = dx*dx + dy*dy;

        return drsqr <= rsqr;
    }
}

//Calculates the intersection point between two line segments
//Port of Paul Bourke's C implementation of a basic algebra method

static class LineIntersector {

  //Epsilon value to perform accurate floating-point arithmetics
  static final float e = 1e-5;

  //Check intersection and calculates intersection point, storing it in a reference passed to the method
  static boolean intersect (float a_x1, float a_y1, float a_x2, float a_y2, 
                            float b_x1, float b_y1, float b_x2, float b_y2, 
                            PVector p) 
  { 
    //Check if lines are parallel
    float d  = ( (b_y2 - b_y1) * (a_x2 - a_x1) ) - ( (b_x2 - b_x1) * (a_y2 - a_y1) );
    if ( abs(d)<e ) return false;    

    //Check if lines intersect
    float na, nb, ma, mb;
    na = ( (b_x2 - b_x1) * (a_y1 - b_y1) ) - ( (b_y2 - b_y1) * (a_x1 - b_x1) );
    nb = ( (a_x2 - a_x1) * (a_y1 - b_y1) ) - ( (a_y2 - a_y1) * (a_x1 - b_x1) );
    ma = na/d;
    mb = nb/d;
    if ( ma<0 || ma>1 || mb<0 || mb>1) return false;
    p.x = a_x1 + ( ma * (a_x2 - a_x1));
    p.y = a_y1 + ( ma * (a_y2 - a_y1));
    return true;
  }

  //We know both lines intersect, so don't check anything, only calculate the intersection point
  static PVector simpleIntersect (float a_x1, float a_y1, float a_x2, float a_y2, 
                                  float b_x1, float b_y1, float b_x2, float b_y2) 
  { 
    float 
    na = ( (b_x2 - b_x1) * (a_y1 - b_y1) ) - ( (b_y2 - b_y1) * (a_x1 - b_x1) ),
    d  = ( (b_y2 - b_y1) * (a_x2 - a_x1) ) - ( (b_x2 - b_x1) * (a_y2 - a_y1) ),
    ma = na/d;
    return new PVector (a_x1 + ( ma * (a_x2 - a_x1)), a_y1 + ( ma * (a_y2 - a_y1)));
  }
}


class Triangle 
{
    PVector p1, p2, p3;

    Triangle()  { p1 = p2 = p3 = null; }

    Triangle(PVector p1, PVector p2, PVector p3) {
        this.p1 = p1;
        this.p2 = p2;
        this.p3 = p3;
    }

    Triangle(float x1, float y1, float x2, float y2, float x3, float y3) 
    {
        p1 = new PVector(x1, y1);
        p2 = new PVector(x2, y2);
        p3 = new PVector(x3, y3);
    } 

    PVector center(){
        return LineIntersector.simpleIntersect(p1.x, p1.y, (p2.x + p3.x)*.5, (p2.y + p3.y)*.5, p2.x, p2.y, (p3.x + p1.x)*.5, (p3.y + p1.y)*.5);  
    }
}


/**
 *  ported from p bourke's triangulate.c
 *  http://astronomy.swin.edu.au/~pbourke/modelling/triangulate/
 *  fjenett, 20th february 2005, offenbach-germany.
 *  contact: http://www.florianjenett.de/
 */

class Triangulator 
{

    class XComparator implements Comparator<PVector> 
    {   
        public int compare(PVector p1, PVector p2) 
        {
            if      (p1.x < p2.x) return -1;
            else if (p1.x > p2.x) return  1;
                                  return  0;     
        }
    }

   class Edge 
   {
        PVector p1, p2;

        Edge() { p1 = p2 = null; }

        Edge(PVector p1, PVector p2) 
        {
            this.p1 = p1;
            this.p2 = p2;
        }
    }

    boolean sharedVertex(Triangle t1, Triangle t2) {
        return t1.p1 == t2.p2 || t1.p1 == t2.p2 || t1.p1 == t2.p3 ||
               t1.p2 == t2.p1 || t1.p2 == t2.p2 || t1.p2 == t2.p3 || 
               t1.p3 == t2.p1 || t1.p3 == t2.p2 || t1.p3 == t2.p3;
    }


    /**
      Triangulation subroutine
      Takes as input vertices (PVectors) in ArrayList pxyz
      Returned is a list of triangular faces in the ArrayList triangles 
      These triangles are arranged in a consistent clockwise order.
    */   
    void triangulate(List<PVector> pxyz, List<Triangle> triangles) 
    { 
      // sort vertex array in increasing x values
      Collections.sort(pxyz, new XComparator());

      // Find the maximum and minimum vertex bounds. This is to allow calculation of the bounding triangle
      float 
      xmin = pxyz.get(0).x,
      ymin = pxyz.get(0).y,
      xmax = xmin,
      ymax = ymin;

      for (PVector p : pxyz) {
        if (p.x < xmin) xmin = p.x;
        else if (p.x > xmax) xmax = p.x;
        if (p.y < ymin) ymin = p.y;
        else if (p.y > ymax) ymax = p.y;
      }

      float 
      dx = xmax - xmin,
      dy = ymax - ymin,
      dmax = dx > dy ? dx : dy,
      two_dmax = dmax*2,
      xmid = (xmax+xmin) * .5,
      ymid = (ymax+ymin) * .5;

      HashSet<Triangle> complete = new HashSet<Triangle>(); // for complete Triangles

      /**
        Set up the supertriangle
        This is a triangle which encompasses all the sample points.
        The supertriangle coordinates are added to the end of the
        vertex list. The supertriangle is the first triangle in
        the triangle list.
      */
      Triangle superTriangle = new Triangle(xmid-two_dmax, ymid-dmax, xmid, ymid+two_dmax, xmid+two_dmax, ymid-dmax);
      triangles.add(superTriangle);

      //Include each point one at a time into the existing mesh
      ArrayList<Edge> edges = new ArrayList<Edge>();
      int ts;
      PVector circle;
      boolean inside;

      for (PVector p : pxyz) {
        edges.clear();

        //Set up the edge buffer. If the point (xp,yp) lies inside the circumcircle then the three edges of that triangle are added to the edge buffer and that triangle is removed.
        circle = new PVector();        

        for (int j = triangles.size()-1; j >= 0; j--) 
        {     
          Triangle t = triangles.get(j);
          if (complete.contains(t)) continue;

          inside = CircumCircle.circumCircle(p, t, circle);

          if (circle.x+circle.z < p.x) complete.add(t);
          if (inside) 
          {
              edges.add(new Edge(t.p1, t.p2));
              edges.add(new Edge(t.p2, t.p3));
              edges.add(new Edge(t.p3, t.p1));
              triangles.remove(j);
          }             
        }

        // Tag multiple edges. Note: if all triangles are specified anticlockwise then all interior edges are opposite pointing in direction.
        int eL = edges.size()-1, eL_= edges.size();
        Edge e1 = new Edge(), e2 = new Edge();

        for (int j=0; j<eL; e1= edges.get(j++)) for (int k=j+1; k<eL_; e2 = edges.get(k++)) 
            if (e1.p1 == e2.p2 && e1.p2 == e2.p1) e1.p1 = e1.p2 = e2.p1 = e2.p2 = null;

        //Form new triangles for the current point. Skipping over any tagged edges. All edges are arranged in clockwise order.
        for (Edge e : edges) {
          if (e.p1 == null || e.p2 == null) continue;
          triangles.add(new Triangle(e.p1, e.p2, p));
        }    
      }

      //Remove triangles with supertriangle vertices
      for (int i = triangles.size()-1; i >= 0; i--) if (sharedVertex(triangles.get(i), superTriangle)) triangles.remove(i);
    }

     /**
      Triangulation subroutine
      Takes as input vertices (PVectors) in ArrayList pxyz
      Returned is a list of triangular faces in the ArrayList triangles 
      These triangles are arranged in a consistent clockwise order.
    */   
    ArrayList<Triangle> triangulate(PVector[] vertices) 
    { 
      int len = vertices.length;

      // sort vertex array in increasing x values
      Arrays.sort(vertices, new XComparator());

      // Find the maximum and minimum vertex bounds. This is to allow calculation of the bounding triangle
      float 
      xmin = vertices[0].x,
      ymin = vertices[0].y,
      xmax = xmin,
      ymax = ymin;

      for (int i=0; i<len; i++) {
        if      (vertices[i].x < xmin) xmin = vertices[i].x;
        else if (vertices[i].x > xmax) xmax = vertices[i].x;
        if      (vertices[i].y < ymin) ymin = vertices[i].y;
        else if (vertices[i].y > ymax) ymax = vertices[i].y;
      }

      float 
      dx = xmax - xmin,
      dy = ymax - ymin,
      dmax = dx > dy ? dx : dy,
      two_dmax = dmax*2,
      xmid = (xmax+xmin) * .5,
      ymid = (ymax+ymin) * .5;

      ArrayList<Triangle> triangles = new ArrayList<Triangle>(); // for the Triangles
      HashSet<Triangle> complete = new HashSet<Triangle>(); // for complete Triangles

      /**
        Set up the supertriangle
        This is a triangle which encompasses all the sample points.
        The supertriangle coordinates are added to the end of the
        vertex list. The supertriangle is the first triangle in
        the triangle list.
      */
      Triangle superTriangle = new Triangle(xmid-two_dmax, ymid-dmax, xmid, ymid+two_dmax, xmid+two_dmax, ymid-dmax);
      triangles.add(superTriangle);

      //Include each point one at a time into the existing mesh
      ArrayList<Edge> edges = new ArrayList<Edge>();
      int ts;
      PVector circle;
      boolean inside;

      for (int v=0; v<len; v++) {
        edges.clear();

        //Set up the edge buffer. If the point (xp,yp) lies inside the circumcircle then the three edges of that triangle are added to the edge buffer and that triangle is removed.
        circle = new PVector();        

        for (int j = triangles.size()-1; j >= 0; j--) 
        {     
          Triangle t = triangles.get(j);
          if (complete.contains(t)) continue;

          inside = CircumCircle.circumCircle(vertices[v], t, circle);

          if (circle.x+circle.z < vertices[v].x) complete.add(t);
          if (inside) 
          {
              edges.add(new Edge(t.p1, t.p2));
              edges.add(new Edge(t.p2, t.p3));
              edges.add(new Edge(t.p3, t.p1));
              triangles.remove(j);
          }             
        }

        // Tag multiple edges. Note: if all triangles are specified anticlockwise then all interior edges are opposite pointing in direction.
        int eL = edges.size()-1, eL_= edges.size();
        Edge e1 = new Edge(), e2 = new Edge();

        for (int j=0; j<eL; e1= edges.get(j++)) for (int k=j+1; k<eL_; e2 = edges.get(k++)) 
            if (e1.p1 == e2.p2 && e1.p2 == e2.p1) e1.p1 = e1.p2 = e2.p1 = e2.p2 = null;

        //Form new triangles for the current point. Skipping over any tagged edges. All edges are arranged in clockwise order.
        for (Edge e : edges) {
          if (e.p1 == null || e.p2 == null) continue;
          triangles.add(new Triangle(e.p1, e.p2, vertices[v]));
        }    
      }

      //Remove triangles with supertriangle vertices
      for (int i = triangles.size()-1; i >= 0; i--) if (sharedVertex(triangles.get(i), superTriangle)) triangles.remove(i);

      return triangles;
    }
}

Answers

  • edited December 2016

    Give us some sample code, not the whole code. It is very long. Also tell what you want the sorting function to do more properly, like should the result be returned in a new ArrayList/array?

    In any case, I seem to have discovered a bug in the forum (in markdown probably). If you see the code fragment, some parts of it are highlighted like comments even though they aren't comments. Is this problem only with my device(runs iOS 9), or does anyone else see this?

  • ... some parts of it are highlighted like comments even though they aren't comments.

    It's a known glitch for when we post code w/ /*. Simply replace all of them w/ /**. *-:)

  • Nice, but why does it occur?

  • displayMesh is not defined.

    we don't have r.jpg.

  • Is the question "how can I sort an ArrayList by custom features of the Triangle class?" Because that is an ArrayList of objects -- if you try to sort it without a custom sort function you are just sorting arbitrary hash idea that represent each object.

  • good point. i'm trying to sort by x and y vector values. so top left to bottom right.

  • If you want sortable objects, use this tutorial:

    https://www.mkyong.com/java/java-object-sorting-example-comparable-and-comparator/

    For more background, discussion etc, the top links on this search:

    https://www.google.com/search?q=java+sortable+object

  • edited December 2016

    http://docs.Oracle.com/javase/8/docs/api/java/util/Arrays.html#sort-T:A-java.util.Comparator-

    http://docs.Oracle.com/javase/8/docs/api/java/util/Comparator.html#compare-T-T-

    http://docs.Oracle.com/javase/8/docs/api/java/lang/Float.html#compare-float-float-

    /**
     * PVector Comparator (v1.0)
     * GoToLoop (2016-Dec-02)
     * forum.Processing.org/two/discussion/19469/sort-a-pvector-array#Item_9
     */
    
    import java.util.Arrays;
    import java.util.Comparator;
    
    static final Comparator<PVector> VEC_CMP = new Comparator<PVector>() {
      @ Override final int compare(final PVector a, final PVector b) {
        int cmp;
        return
          (cmp = Float.compare(a.x, b.x)) != 0? cmp :
          (cmp = Float.compare(a.y, b.y)) != 0? cmp :
          Float.compare(a.z, b.z);
      }
    };
    
    static final int VECS = 5, MAX_VAL = 10;
    final PVector[] vecs = new PVector[VECS];
    
    void setup() {
      for (int i = 0; i < VECS; ++i)
        vecs[i] = PVector.random3D(this).mult(random(MAX_VAL));
    
      printArray(vecs);
      println();
    
      Arrays.sort(vecs, VEC_CMP);
      printArray(vecs);
      println();
    
      Arrays.sort(vecs, VEC_CMP.reversed());
      printArray(vecs);
    
      exit();
    }
    
  • @GoToLoop -- thanks for sharing the concise Comparator demo, really helpful.

  • edited December 2016 Answer ✓

    i'm trying to sort by x and y vector values. so top left to bottom right.

    I think it is always useful to be able to visualize the output to confirm it is the result you want. So I have modified GoToLoop's example first to work in 2D since the OP is working in 2D and then display the unsorted (green) and the sorted (black) graphs of the connected vectors.The result is shown here but I am not sure this is what the OP wants.

    sorted

    import java.util.Arrays;
    import java.util.Comparator;
    
    static final Comparator<PVector> VEC_CMP = new Comparator<PVector>() {
      @ Override final int compare(final PVector a, final PVector b) {
        int cmp;
        return
          (cmp = Float.compare(a.x, b.x)) != 0? cmp :
          Float.compare(a.y, b.y);
      }
    };
    
    static final int VECS = 50, MAX_VAL = 200;
    final PVector[] vecs = new PVector[VECS];
    
    void setup() {
      size(400, 400);
      background(240);
      strokeWeight(1.2);
      translate(width/2, height/2);
      for (int i = 0; i < VECS; ++i)
        vecs[i] = PVector.random2D(this).mult(random(MAX_VAL));
      // Before sort (green)
      stroke(0, 255, 0);
      for (int i = 1; i < vecs.length; i++)
        line(vecs[i-1].x, vecs[i-1].y, vecs[i].x, vecs[i].y);
      // Sort them
      Arrays.sort(vecs, VEC_CMP);
      // After sort (black)
      stroke(0);
      for (int i = 1; i < vecs.length; i++)
        line(vecs[i-1].x, vecs[i-1].y, vecs[i].x, vecs[i].y);
    
      save("sorted.png");
    }
    
  • edited December 2016

    @quark -- your example sorts the coordinates by their x axis. Isn't that exactly what OP asked for -- coordinates in order from low to high?

    Edit: Ah. "top left to bottom right" -- so sorted along the x==y axis. Got it.

  • great thanks, everyone.

    i did want top left to bottom right, but i don't need you to write the code for me, you've set me off on the right tracks.

    appreciate the input.

  • edited December 2016

    quark:

    the unsorted (green) and the unsorted (black)

    // Before sort (green)
    
    // After sort (green)
    

    slight errors in the description / comments i think

  • @koogs well spotted I have corrected it. Thanks

  • edited December 2016

    @jeremydouglass I think he means this -

    sorted

  • I have corrected it.

    comments are still wrong... 8)

  • I fixed the text and missed the comments. NOW they are fixed :D

  • Cool, thanks

  • I've marked this as answered but if anyone can show how to do this with an array list, rather than an array that would help.

  • edited December 2016

    There's a sort defined for Collections as well as Arrays. This'll take a List (which ArrayList implements)

    https://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.List,%20java.util.Comparator)

    (Link mangled by forum parser, you'll need to cut and paste)

    I haven't tried this...

  • @koogs try using HTML directly. I think it is supposed to set such problems.
    Test link same as above.

  • Answer ✓

    My previous code changed to make use of ArrayLists

    import java.util.Collections;
    import java.util.Comparator;
    
    static final Comparator<PVector> VEC_CMP = new Comparator<PVector>() {
      @ Override final int compare(final PVector a, final PVector b) {
        int cmp;
        return
          (cmp = Float.compare(a.x, b.x)) != 0? cmp :
          Float.compare(a.y, b.y);
      }
    };
    
    static final int VECS = 50, MAX_VAL = 200;
    final ArrayList<PVector> vecs = new ArrayList<PVector>();
    
    void setup() {
      size(400, 400);
      background(240);
      strokeWeight(1.2);
      translate(width/2, height/2);
      for (int i = 0; i < VECS; ++i)
        vecs.add(PVector.random2D(this).mult(random(MAX_VAL)));
      // Before sort (green)
      stroke(0, 255, 0);
      PVector prev = vecs.get(0);
      for (int i = 1; i < vecs.size(); i++) {
        PVector curr = vecs.get(i);
        line(prev.x, prev.y, curr.x, curr.y);
        prev = curr;
      }
      // Sort them
      Collections.sort(vecs, VEC_CMP);
      // After sort (black)
      stroke(0);
      prev = vecs.get(0);
      for (int i = 1; i < vecs.size(); i++) {
        PVector curr = vecs.get(i);
        line(prev.x, prev.y, curr.x, curr.y);
        prev = curr;
      }
      save("sorted.png");
    }
    
  • you guys are legends. all sorted now - and me all the more wiser.

  • Just for completeness' sake, my original sketch converted from regular array to ArrayList. ;;)

    http://docs.Oracle.com/javase/8/docs/api/java/util/Collections.html#sort-java.util.List-java.util.Comparator-

    /**
     * PVector Comparator (v2.0)
     * GoToLoop (2016-Dec-05)
     * forum.Processing.org/two/discussion/19469/sort-a-pvector-array#Item_25
     */
    
    import java.util.List;
    import java.util.Collections;
    import java.util.Comparator;
    
    static final Comparator<PVector> VEC_CMP = new Comparator<PVector>() {
      @ Override final int compare(final PVector a, final PVector b) {
        int cmp;
        return
          (cmp = Float.compare(a.x, b.x)) != 0? cmp :
          (cmp = Float.compare(a.y, b.y)) != 0? cmp :
          Float.compare(a.z, b.z);
      }
    };
    
    static final int VECS = 5, MAX_VAL = 10;
    final List<PVector> vecs = new ArrayList<PVector>(VECS);
    
    void setup() {
      for (int i = 0; i < VECS; ++i)
        vecs.add(PVector.random3D(this).mult(random(MAX_VAL)));
      println(vecs, ENTER);
    
      Collections.sort(vecs, VEC_CMP);
      println(vecs, ENTER);
    
      Collections.sort(vecs, VEC_CMP.reversed());
      println(vecs);
    
      exit();
    }
    
Sign In or Register to comment.