[squeak-dev] Rectangle >> intersects: "degenerate case" -- *wrong* behavior??

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Thu Jan 17 21:08:19 UTC 2013

I understand how brittle it may seem...
But that's how #intersect: works, when there is no intersection, it
answers a Rectangle with negative width and/or height

So we have not that many options... (unless we go in tons of rewrites
and broken compatibility).
I took above feature as granted, rationalized the implementation
stating that rectangle with negative width/height is empty, and
documented it with SUnit TestCase
That's the minimum change that can possibly work.
I just was a bit too zealous, there is a thin line between empty and
empty, thanks for raising your voice, it's now corrected in trunk :)

If you change #origin:corner: to either answer a correct Rectangle or
raise an Error, you'll break #intersect: and maybe other senders who
There is a #vertex:vertex: creation message in Visualworks for exactly
that purpose...
In Squeak, it seems we never had the need/idea of it, but you can also
write it ^Rectangle encompassing: {vertex1. vertex2}.

Note that #intersect: #intersects: and #areasOutside: are essential
for Morphic redrawing for example...


2013/1/17 Jim Rosenberg <jr at amanue.com>:
> --On Tuesday, January 15, 2013 01:49:26 +0100 Nicolas Cellier
> <nicolas.cellier.aka.nice at gmail.com> wrote:
>> Well, the old behavior of intersects: was wrong with respect to intersect:
>> This is because intersect: answer an "empty" rectangle (negative width
>> or height).
>> Such intersection HAS TO BE EMPTY, and thus cannot intersects: anything...
>> To accomodate the degenerated case (one null dimension, the other
>> positive or null) we can change the final tests to strict
>> inequalities. OK?
> Hmm ...
> I guess changing to strict inequality would be OK with *me* -- as far as not
> breaking any of my own code -- but I'm still wondering whether silently
> returning false from Rectangle >> intersects: in the case of "negative
> height" or "negative width"  is the right behavior.
> The issue here, as I understand it, is that a "rectangle" where the origin
> and corner are not top-left and bottom-right is "incorrectly specified". So,
> if Rectangle >> intersects: can't really handle an incorrectly specified
> rectangle, should it return false, or throw an error?
> Of course changing the behavior to throw an error could break somebody
> else's code, which I wouldn't want to do.
> What should Rectangle origin: (25 at 250) corner: (100 at 100) produce? A
> rectangle starting from (25 at 250) and ending at (100 at 100) certainly makes
> semantic sense. But it's "incorrectly specified". Should it throw an error?
> Should it produce the same thing as
> Rectangle origin: (25 at 100) corner: (100 at 250)? Should there be a new class
> method, say Rectangle from: (25 at 250 to: (100 at 100) which would be guaranteed
> to produce the rectangle with origin (25 at 100) and corner (100 at 250)? Should
> Rectangle >> intersects: "normalize" both the receiver and argument before
> calculating whether things intersect?
> What "is" a rectangle? How is the Squeak user supposed to know? There are at
> least two interpretations of what "rectangle" might mean:
> (1) a 4-sided polygon where all 4 sides are strictly horizontal or strictly
> vertical, determined by two diagonally opposite points.
> (2) a 4-sided polygon where all 4 sides are strictly horizontal or strictly
> vertical, determined by the top-left point ("origin") and bottom-right point
> ("corner").
> Maybe I'm being unfair, but it seems to me things aren't really clear from
> one method to the next what the semantics are supposed to be. I'm getting
> the idea that the intent is that the semantics of "rectangle" are supposed
> to be (2). Well, OK, as long as we all know that; but in this case,
> shouldn't Rectangle origin: (25 at 250) corner: (100 at 100) throw an error?
> But then that's almost certain to break *somebody's* code ...
> It's a puzzle.

More information about the Squeak-dev mailing list