Polygon.contains() returns false?!

V

VisionSet

In the method below triangle is a java.awt.Polygon

public boolean contains(Point2D p) {
int x1 = triangle.xpoints[0];
int x2 = triangle.xpoints[1];
int x3 = triangle.xpoints[2];
int y1 = triangle.ypoints[0];
int y2 = triangle.ypoints[1];
int y3 = triangle.ypoints[2];
System.out.println("triangle x: "+x1+", "+x2+", "+x3);
System.out.println("triangle y: "+y1+", "+y2+", "+y3);
System.out.println("point: "+p);
System.out.println("contains? "+triangle.contains(p));
return triangle.contains(p);
}

produces the following:

triangle x: 156, 156, 2
triangle y: 108, 2, 108
point: java.awt.Point[x=149,y=100]
contains? false

Now I might be missing something, but how can it return false?

Any ideas?
 
R

Roedy Green

In the method below triangle is a java.awt.Polygon

show us the code you used to construct triangle.

What winding rule are you using? Did you order the points in
clockwise or counter clockwise order?
 
V

VisionSet

Roedy Green said:
show us the code you used to construct triangle.


triangle.xpoints[0] = c.x+index*c.width;
triangle.xpoints[1] = c.width+c.x;
triangle.xpoints[2] = c.x;
triangle.ypoints[0] = c.y+index*c.height;
triangle.ypoints[1] = c.y;
triangle.ypoints[2] = c.height+c.y;

Which result in a clockwise triangle when index is 0 and an anti cw one when
index is 1. (c is a Rectangle)
What winding rule are you using?

Polygon states that it uses WIND_EVEN_ODD winding rule. There is no way of
changing it I can see, in Polygon or PathIterator.
Did you order the points in
clockwise or counter clockwise order?

I have read the winding rule notes, can't see a mention of clockwise/anti
clockwise.

Anyway, yes, I have one triangle constructed clockwise, and another anti cw.
The only one that ever gives me trouble is the anti cw one. Hadn't even
considered it was anti cw until I examined it! Why the heck should it
matter? More to the point why isn't that fact mentioned in Polygon docs?

Anyhow, I've changed it to clockwise and *so far* it is okay.

Thanks Roedy, I'd be interested in the whys and wherefores...
 
R

Roedy Green

Thanks Roedy, I'd be interested in the whys and wherefores...

You can read the PostScript Red Book, (now white) which explains all
this on page 70.

http://www.amazon.com/exec/obidos/ASIN/0201379228/canadianmindprod


You can draw some clockwise and counter clockwise triangles, and pick
some points "inside" and outside, and apply the rules and see what
happens.

Do the calculation with alternate winding rules.


Winding rules help determine what is inside and outside when you have
donut shapes with the hole ordered one way and the outside another.
Direction matters!!

For ordinary morals, the non-zero winding rule is more intuitive.
 
V

VisionSet

Anyhow, I've changed it to clockwise and *so far* it is okay.

Oh no it isn't!! Seemed to help a bit (falls down less often).

Incidentally the old debug gave:

triangle x: 156, 156, 2 // anticlockwise
triangle y: 108, 2, 108
point: java.awt.Point[x=149,y=100]
contains? false

The new debug gives:

triangle x: 2, 156, 156 // clockwise
triangle y: 108, 2, 108
point: 144.0,87.0
contains? false

Help!

TIA
 
R

Roedy Green

Oh no it isn't!! Seemed to help a bit (falls down less often).

See http://mindprod.com/jgloss/coordinates.html

Java does not use the same co-ordinate system as Descartes.

Try drawing on piece of graph paper with 0.1 inch grid. Each grid
square is a pixel.

The other possible thing to consider is you are working with integers.
When you create triangles only a few pixels tall, it gets a bit less
clear what's inside and outside. This isn't PostScript!
 
F

Fahd Shariff

I dont see y you should be getting "false".

I tried it out and ended up with true all the time. Heres my hack:

import java.awt.* ;
import java.awt.geom.* ;

public class Tester
{
public static void main(String[] args)
{
int[] x = {156,156,2} ;
int[] y = {108,2,108} ;
Polygon p = new Polygon(x,y,3) ;

//test1
System.out.println(p.contains(149,100));

//test2 using point2d
Point2D point = new Point2D.Double(149,100) ;
System.out.println(point) ;
System.out.println(p.contains(point));

//test3 using point
Point point2 = new Point(149,100) ;
System.out.println(point2) ;
System.out.println(p.contains(point2));

//test4 using point2d and point
Point2D point3 = new Point(149,100) ;
System.out.println(point3) ;
System.out.println(p.contains(point3));

}
}

Output:

true
Point2D.Double[149.0, 100.0]
true
java.awt.Point[x=149,y=100]
true
java.awt.Point[x=149,y=100]
true

Sorry, i don't know what your problem is...

Fahd
 
V

VisionSet

Roedy Green said:
See http://mindprod.com/jgloss/coordinates.html

Java does not use the same co-ordinate system as Descartes.

Try drawing on piece of graph paper with 0.1 inch grid. Each grid
square is a pixel.

The other possible thing to consider is you are working with integers.
When you create triangles only a few pixels tall, it gets a bit less
clear what's inside and outside. This isn't PostScript!

These problems emmerge when my GUI is maximised, the components are c.
150x100 pixels!

Look at the debug output, these coordinates are miles inside!
 
V

VisionSet

Fahd Shariff said:
I dont see y you should be getting "false".

I tried it out and ended up with true all the time.

Thanks for you trouble, I can well believe it. My program only does this
intermittently, and then only when the components are large.
I thought maybe another thread may be changing the point, but the way I have
the method debugging now I don't see how that is possible:

public boolean contains(Point2D p) {
double px = p.getX();
double py = p.getY();
int x1 = triangle.xpoints[0]; // triangle is a java.awt.Polygon
int x2 = triangle.xpoints[1];
int x3 = triangle.xpoints[2];
int y1 = triangle.ypoints[0];
int y2 = triangle.ypoints[1];
int y3 = triangle.ypoints[2];
System.out.println("triangle x: "+x1+", "+x2+", "+x3);
System.out.println("triangle y: "+y1+", "+y2+", "+y3);
System.out.println("point: "+px+","+py);

boolean boo = triangle.contains(px, py);

System.out.println("contains? "+boo);
return boo;
}
Once gave me:
triangle x: 2, 156, 156
triangle y: 108, 2, 108
point: 144.0,87.0
contains? false

Can anyone see how a point well inside could possibly return false by the
above method?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top