1

I am doing a Jarvis' march (wrapping) program, in which I need to return a set of the points on the convex hull. I am getting the correct points, for example [L0, L1, L2] but it needs to be ["L1", "L2", "L3"].

When adding the results to the set, I have used "\"" + temp.point + "\"" and also '"' + temp.point + '"', but they both end up swapping my final results.

public static Set<String> getBoundary (String sectorFile){

        Set<String> points = new HashSet<>();
        public static Set<String> getBoundary(String sectorFile){

    Set<String> points=new HashSet<>();
    Set<Point> vals=new HashSet<>();
    Vector<Point> hull=new Vector<Point>();

    try(Scanner s=new Scanner(new File(sectorFile))){

        s.useDelimiter("[\\\\|\\n\\r]+");
        while(s.hasNext()){
            String point=s.next();
            double x=s.nextDouble();
            double y=s.nextDouble();

            Point xy=new Point(point,x,y);

            xy.setPoint(point);
            xy.setX(x);
            xy.setY(y);

            vals.add(xy);

        }

        Point[]values=new Point[vals.size()];

        vals.toArray(values);

        int l=0;
        for(int i=1;i<vals.size();i++)
            if(values[i].x<values[l].x)
                l=i;

        // Start from leftmost point, keep moving  
        // counterclockwise until reach the start point 

        int p=l,q;
        do
        {
            // Add current point to result 
            hull.add(values[p]);

            q=(p+1)%vals.size();

            for(int i=0;i<vals.size();i++)
            {

                if(orientation(values[p],values[i],values[q])==2)
                    q=i;
            }

            p=q;

        }while(p!=l);  // While we don't come to first  
        // point 

        for(Point temp:hull)
            points.add(temp.point);

    }catch(FileNotFoundException e){
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return points;
}
private static class Point
{
    String point;
    double x, y;

    Point(String point, double x, double y){

        this.point = point;
        this.x=x;
        this.y=y;
    }

    private void setPoint(String i) {
        this.point = i;
    }

    private void setX (double x) {
        this.x = x;
    }

    private void setY (double y) {
        this.y = y;
    }

}

Expected

["L0", "L1", "L2"]

Actual

["L2", "L1", "L0"]
Butiri Dan
  • 1,759
  • 5
  • 12
  • 18

1 Answers1

4

Big misconceptions: sets do not have an order. You can't rely on a HashSet to give you elements in the same "order" at all.

If at all, you could use a LinkedHashSet (the you receive your elements in insertion order). The other alternative would be a TreeSet that does implicit sorting of all elements. If those two options don't work for your requirements, then you should consider to use a completely different container structure instead.

Also note: to reasonably use objects within a HashSet, their class should @Override equals() and hashCode() (see here for example). Your point class does not, and that will sooner or later lead to very unexpected behavior!

Finally: of course, when you have two sets, you can compare them (as in set theory: do they have identical content, or an intersection, or no intersection at all). And assuming that your Point class has a reasonable equals() method, that is probably what you want: to compare that two sets contain the exact same Points.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • So, in theory, my professor is probably going to compare my returned set to make sure them contain the same amount and name of my points vs. them being in the same order? And thank you for the @Override equals() and hashCode() example! – Michael Harrison Aug 02 '19 at 15:40
  • 1
    @MichaelHarrison I think you should talk to your professor here. The only thing I can tell you: sets do not have order. When you compare two sets, then you only compare if the entries match up (and of course: therefore it is really important that two Points show up as equal when they have the same x/y for example). Maybe also ask about that "point" String field in the Point class. That looks very much ... pointless. – GhostCat Aug 02 '19 at 15:43
  • Your options to get items out of a `Set` are iterator or array. Calling `iterator()`: "_Returns an iterator over the elements in this set. The elements are returned in no particular order (unless this set is an instance of some class that provides a guarantee)._" Calling `toArray()`: "_Returns an array containing all of the elements in this set. If this set makes any guarantees as to what order its elements are returned by its iterator, this method must return the elements in the same order._" If you want ordering, look at `TreeSet`. – Kaan Aug 02 '19 at 15:56