3 Replies Latest reply: Apr 29, 2013 3:31 AM by ptoye RSS

    Problems with Path2D: "contains" method does not seem to work

    ptoye
      I'm having a problem with the contains method of Path2D (or rather GeneralPath which inherits from it). As far as I can see the point is well inside the path, but the "contains" method returns false. I can't find any tutorials on this site which might help out, and the API documentation doesn't help either.

      I'm not 100% sure of the significance of the "winding rule" but whatever I set it to doesn't make any difference.

      Is there some co-ordinate origin that I have to take into account?

      Here's some fairly self-explanatory debugging output - the path is a nearly-full square from 3 to 180 and the point is 64,64 which is fairly central in that square.



      Winding rule: 1 // PathIterator.WIND_NON_ZERO
      Point: 64, 64
      Segment type 0; 16.0, 3.0
      Segment type 1; 178.0, 3.0
      Segment type 1; 178.0, 178.0
      Segment type 1; 3.0, 178.0
      Segment type 1; 3.0, 14.0

      [Later]
      This is stranger that I thought. The code is:
            int SquareX=s.getX();
            int SquareY=s.getY();
            if (!s.isMarked() && !(border.contains(SquareX, SquareY))) {
              TestKiller.showMessage("Region " + id + " contains non-contiguous square " + s.getXIndex()
                      + "," + s.getYIndex());
              String DebugString="Winding rule: "+border.getWindingRule() + "\n";
              DebugString+="Point: " + (SquareX) + ", " +(SquareY ) + "\n";
              DebugString+="Marked: "+s.isMarked()+"\n";
              DebugString+="Contains: " + border.contains(SquareX, SquareY)+"\n";
              PathIterator PI=border.getPathIterator(null);
              double[] Coords=new double[6];
              int Type;
              do {
                Type=PI.currentSegment(Coords);
                DebugString+= "Segment type " + Type + ": "+ Coords[0]+", " + Coords[1]+"\n";
                PI.next();
              } while (!PI.isDone());
              TestKiller.showMessage(DebugString);
              System.out.println(DebugString);
              
              ok = false;
            } 
      And the output is:

      Winding rule: 1
      Point: 64, 64
      Marked: false
      Contains: true
      Segment type 0: 16.0, 3.0
      Segment type 1: 178.0, 3.0
      Segment type 1: 178.0, 178.0
      Segment type 1: 3.0, 178.0
      Segment type 1: 3.0, 14.0


      So the conditional should be entered only if IsMarked and Contains are both false. But the output shows that this isn't true!

      Edited by: ptoye on Apr 28, 2013 8:13 AM
        • 1. Re: Problems with Path2D: "contains" method does not seem to work
          Maxideon
          The output is saying that contains() returns true. I agree that the if statement wouldn't be executed if contains does returns true. But since it does, then that isn't the exact code you compiled and ran. You're doing something else.

          Or is your claim that contains() is sometimes returning false (for the if statement) and sometimes returning true (for the debugString)?
          • 2. Re: Problems with Path2D: "contains" method does not seem to work
            ptoye
            OK, the code isn't 100% the same: there's a line which displays a Dialog box to let me know that there's been a error.

            If I take this out, the call to "contains" now returns False, and the values of the elements in the path have changed as well (so the point is no longer inside the path). The output is now:

            Winding rule: 1
            Point: 64, 64
            Marked: false
            Contains: false
            Segment type 0: 18.0, 5.0
            Segment type 1: -6.0, 5.0
            Segment type 1: -6.0, -6.0
            Segment type 1: 5.0, -6.0
            Segment type 1: 5.0, 16.0


            So the question has now changed to: how does displaying a Dialog box (and then of course clicking a button to make it disappear) affect the contents of a GeneralPath? As far as I can see, the only thing that's changed is the position of the cursor. I'll have to investigate more, but in the meantime any ideas are welcome.

            [Following investigation]
            It seems that for reasons that I have yet to determine, the routine is being interrupted by a FormComponentResized event which is calling it recursively - between the conditional and the message appearing the conditions have changed and the shape of the path recalculated - so the condition becomes true by the time the message appears.

            So it seems that "contains" works properly (which isn't surprising) but a synchronisation bug in my code.

            Edited by: ptoye on Apr 29, 2013 1:23 AM - reason for problem found.
            • 3. Re: Problems with Path2D: "contains" method does not seem to work
              ptoye
              Turned out to be a synchronisation bug in my cope - nothing wrong with Path2D.