[squeak-dev] intersect: when intsersects: is false

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Sun Jun 20 12:46:10 UTC 2010


Playing with empty rectangles:
(I'll try to not get caught by a premature gmail send shortcut)

(0 at 0 corner: 0 at 0) containsPoint: 0 at 0 -> false.
Thus, yes, it is an empty rectangle.

(0 at 0 corner: -1 @ -1) = (0 at 0 corner: 0 at 0) -> false.
Two empty rectangles can be different though...

(100 @ 100 corner: 50 @ 50) center -> (75 at 75).
Des not have the same center as (0 at 0 corner: 0 at 0).

((0 at 0 corner: 0 at 0) merge: (100 @ 100 corner: 50 @ 50)) -> (0 at 0 corner: 50 at 50).
Merging two empty rectangles can result in a non empty rectangle.

 (100 @ 100 corner: 50 @ 50) area -> 0.

((0 at 0 corner: 0 at 0)  pointNearestTo: 50 at 100) -> (0 at 0).
((0 at 0 corner: -1 @ -1)  pointNearestTo: 50 at 100) -> (-1 at -1).
((100 @ 100 corner: 50 @ 50) pointNearestTo: 50 at 100) -> (50 at 50).

((100 at 100 corner: 50 at 50) intersects: (40 at 40 corner: 110 at 110)) -> true.
((100 at 100 corner: 50 at 50) intersect: (40 at 40 corner: 110 at 110)) ->
(100 at 100 corner: 50 at 50).
An empty rectangle can intersect a non empty one, though the
intersection is an empty rectangle. Funny...

All in all, it may not be a good idea to return (0 at 0 corner: 0 at 0) in
all cases...
It is just another empty rectangle, maybe not the one you want.
Maybe we could just implement #isEmpty...
Oh wait, it is just named #hasPositiveExtent.

Nicolas

2010/6/20 Nicolas Cellier <nicolas.cellier.aka.nice at gmail.com>:
> 2010/6/20 Joachim Geidel <joachim.geidel at onlinehome.de>:
>> Whatever is thought to be the "correct" answer, please have a look at the
>> result of this method in other Smalltalk dialects. I recently had the
>> unpleasant experience of having to work around minor incompatibilities
>> between VisualWorks, Squeak and Pharo. Please don't add another one. OTOH,
>> if it is already different, that would a chance for unification.
>>
>> >From the point of view of correctness: There is no such thing as a Rectangle
>> which is the intersection of non-intersecting rectangles. The "correct"
>> answer could be to raise an exception, similar to what happens for a
>> division by zero, or to answer nil. Both would certainly break a lot of
>> existing code. (0 at 0) corner: (0 at 0) is completely wrong IMO. While it is
>> empty in a mathematical sense, it would give you answers for #origin and
>> #corner and many other messages which are complete nonsense. One could just
>> leave it as it is, because the precondition for answering a "correct"
>> rectangle is that the receiver and the argument intersect. If the don't, the
>> answer is undefined, which means that whatever is answered is correct in a
>> mathematical sense. So the third option besides nil and an exception would
>> be to document the precondition in the method's comment.
>>
>> Whatever you do, please keep it compatible with other Smalltalk dialects!
>>
>> Just my 2c.
>> Joachim Geidel
>>
>> Am 20.06.10 10:36 schrieb Frank Shearar:
>>
>>> On 2010/06/20 00:58, Jim Rosenberg wrote:
>>>> [Using Squeak 3.8; apologies if more current versions "fix" this ... ]
>>>>
>>>> This expression yields false:
>>>>
>>>> ((0 at 0) corner: (50 at 50)) intersects: ((100 at 100) corner: (150 at 150))
>>>>
>>>> So, what should this yield?:
>>>>
>>>> ((0 at 0) corner: (50 at 50)) intersect: ((100 at 100) corner: (150 at 150))
>>>>
>>>> I was expecting perhaps nil. Instead I got (100 at 100) corner: (50 at 50).
>>>> This is "a surprise". It's certainly not right mathematically ...
>>>
>>> It's still that way in trunk, at any rate.
>>>
>>> I do think that the current behaviour's wrong.
>>>
>>> In the interest of keeping the result of a #intersect: uniform, we could
>>> return Rectangle origin: (0 at 0) corner: (0 at 0) instead of nil. (And we can
>>> put that long expression inside a new method,
>>> Rectangle>>emptyRectangle.) Then we could compose multiple #intersect:s
>>> without special-casing anything.
>>>
>>> I think we just need a guard clause like
>>>
>>>      | aPoint left right top bottom |
>>>      (self intersects: aRectangle) ifFalse: [^ self emptyRectangle].
>>>
>>>      "Rest of #intersect goes here."
>>>
>>> but I'm sure Nicolas Cellier will weigh in with a definitive answer :)
>>>
>>> frank
>>>
>>
>>
>>
>>
>
> Well, I never have a definitive answer - though I pedantically may seem to :)...
> What I usually suggest is to put enough brain storming to help
> reaching an answer that is least surprising indeed.
> To me, least-surprising includes:
> - uniform thru the library
> - mathematically well grounded
> The other rationale to be taken into account is simplicity.
> And of course, cross-dialect compatibility is another pragmatic POV.
>
> Nicolas
>



More information about the Squeak-dev mailing list