Skip to main content

Area.isRectangular() behaves differently on Area's that are equal. A bug?

4 replies [Last post]
pietblok
Offline
Joined: 2003-07-17

Hi,

Under certain conditions I find the following:

<br />
Area a, b;<br />
a.equals(b) && b.equals(a) && ! (a.isRectangular && b.isRectangular())<br />

Is this a bug? Or am I missing something?

The following code demonstrates the problem:

<br />
import java.awt.Polygon;<br />
import java.awt.Rectangle;<br />
import java.awt.geom.AffineTransform;<br />
import java.awt.geom.Area;<br />
import java.awt.geom.Rectangle2D;</p>
<p>public class TestArea {</p>
<p>    public static void main(String[] args) {<br />
	Area horizontal = new Area();<br />
	for (int x = 0; x < 2; x++) {<br />
	    horizontal.add(new Area(new Rectangle2D.Double(x, 0, 1, 1)));<br />
	}<br />
	print("Horiz.", horizontal);</p>
<p>	Area vertical = new Area();<br />
	for (int y = 0; y < 2; y++) {<br />
	    vertical.add(new Area(new Rectangle2D.Double(0, y, 1, 1)));<br />
	}<br />
	print("Vert.", vertical);</p>
<p>	Area square = new Area();<br />
	for (int x = 0; x < 2; x++) {<br />
	    for (int y = 0; y < 2; y++) {<br />
		square.add(new Area(new Rectangle2D.Double(x, y, 1, 1)));<br />
	    }<br />
	}<br />
	print("Square", square);</p>
<p>	/*<br />
	 * Now is there a difference between a rotated square and a<br />
	 * polygon that, in effect, represents a rotated square.<br />
	 */<br />
	System.out.println();</p>
<p>	Area rotated = new Area(new Rectangle(1, 1, 1, 1));<br />
	rotated.transform(AffineTransform.getRotateInstance(Math.PI / 4, 1.5, 1.5));<br />
	print("Rotated", rotated);</p>
<p>	Area polygon = new Area(new Polygon(new int[] { 1, 2, 1, 0 },<br />
		new int[] { 0, 1, 2, 1 }, 4));<br />
	print("Polygon", polygon);<br />
    }</p>
<p>    public static void print(String name, Area a) {<br />
	Area b = new Area(a.getBounds2D());<br />
	System.out.println(name</p>
<p>	+ "\t a.equals(b): " + a.equals(b)</p>
<p>	+ "\t b(equals(a): " + b.equals(a)</p>
<p>	+ "\t b.isRectangular(): " + b.isRectangular()</p>
<p>	+ "\t a.isRectangular(): " + a.isRectangular()</p>
<p>	);<br />
    }</p>
<p>}<br />

This is the output I get:

[pre]Horiz. a.equals(b): true b(equals(a): true b.isRectangular(): true a.isRectangular(): true
Vert. a.equals(b): true b(equals(a): true b.isRectangular(): true a.isRectangular(): false
Square a.equals(b): true b(equals(a): true b.isRectangular(): true a.isRectangular(): false

Rotated a.equals(b): false b(equals(a): false b.isRectangular(): true a.isRectangular(): false
Polygon a.equals(b): false b(equals(a): false b.isRectangular(): true a.isRectangular(): false
[/pre]
(An additional test examens the behaviour of a rotated Area and an Area that is filled with a polygon that, in effect, represents a rotated square)

Tested under Windows XP and java 6u3.

Thanks for any insights

Piet

Message was edited by: pietblok

Message was edited by: pietblok

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Jim Graham

This is probably due to the fact that the Area class does not optimize
the case of 2 rectangular areas which abut each other top and bottom
into a single rectangular area, but it does optimize the horizontal case.

The isRectangular() method performs a trivial check for a single outline
with 4 sides, not a more exhaustive comparison to the area that the
various pieces cover. In the case of a shape that wasn't optimized by
the calculations it may not notice that the result is square. Also, its
definition of rectangular is specific to an axis aligned rectangle so
your 45 degree rotated square polygon would not evaluate as rectangular
as per the intent of its implementation, though the spec doesn't quite
call this out (unless your definition of rectangle assumes axis
alignment which may be true of the Rectangle class, but not of the
common English term "rectangular"). We should probably clarify that in
the method comments.

The equals() method does perform the more exhaustive comparison/tests
that notice that the area is equal when you compare it to its bounds
rectangle. Obviously this fails for the 45 degree rotated square
polygon that you test so the answers in that case are consistent with
the above clarification of the definition of isRectangular()...

...jim

java2d@JAVADESKTOP.ORG wrote:
> Hi,
>
> Under certain conditions I find the following:
>
> [code]
> Area a, b;
> (a.equals(b) && b.equals(a)) != (a.isRectangular && b.isRectangular())
> [/code]
> Is this a bug? Or am I missing something?

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

pietblok
Offline
Joined: 2003-07-17

Thank you Jim,

Yes, I think you are right that the term rectangular in the documentation needs clarification. Just because I wanted to know what rectangular means in this context, I added the rotated tests.

And yes, the cause of one area being rectangular and the other not, while both being equal, will have to do with the trivial check that is made. The implementer apparently did not read the last sentence of the class description, that says:

" The analysis that the Area class must perform on the path may not reflect the same concepts of "simple and obvious" as a human being perceives. "

My question remains: am I right in stating that

a.equals(b) && b.equals(a) && a.isRectangular != b.isRectangular()

never should be true?

In that case I will file a bug report.

Piet

Jim Graham

Hi Piet,

java2d@JAVADESKTOP.ORG wrote:
> Thank you Jim,
>
> Yes, I think you are right that the term rectangular in the documentation needs clarification. Just because I wanted to know what rectangular means in this context, I added the rotated tests.

I submitted Bug 6650197 yesterday to track this issue.

> And yes, the cause of one area being rectangular and the other not,
> while both being equal, will have to do with the trivial check that
> is made. The implementer apparently did not read the last sentence of
> the class description, that says:
> " The analysis that the Area class must perform on the path may not
> reflect the same concepts of "simple and obvious" as a human being
> perceives. "

I'm not sure who you are referring to as "the implementer" there. The
"last sentence" that you quote was written by "the implementer" of the
Area class to inform the developer of a caveat related to its
processing. In some sense, that sentence "relaxes" the API guarantees
in a non-specific way.

> My question remains: am I right in stating that
>
> a.equals(b) && b.equals(a) && a.isRectangular != b.isRectangular()
>
> never should be true?

It may be true sometimes, but don't count on it.

> In that case I will file a bug report.

See the above bug 6650197 which may cover the issues already...

...jim

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

pietblok
Offline
Joined: 2003-07-17

Thank you Jim.