BUG?: Rectangle class>>#center:extent:

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

BUG?: Rectangle class>>#center:extent:

Keith Alcock
After lots of searching I finally figured out why various parts of my
views weren't aligning correctly.  Rectangles made based on a center
point and an extent have their extents silently rounded to an integer
multiple of 2 (via //) in the following methods:

Rectangle class>>center: aPoint extent: aPointExtent
        "Answer an instance of the receiver of aPointExtent centred on aPoint"

        ^self origin: aPoint - (aPointExtent // 2) extent: aPointExtent

Rectangle>>center
        "Answer the point at the centre of the receiver."

        ^origin + (self extent // 2)

Rectangle>>center: aPoint
        "Centres the receiver over aPoint. The extent remains the same"

        self position: (aPoint - (self extent // 2))

I don't believe there is any requirement that the points or dimensions
of a rectangle be integers at all, much less multiples of 2.  Since
these functions are probably used for centering windows and Windows
doesn't like non-integer coordinates, I can imagine where the code
originated.  However, the general Rectangle class is not the proper
place for such a conversion I would like to request that it be
(re)moved.

Keith Alcock


Reply | Threaded
Open this post in threaded view
|

Re: Rectangle class>>#center:extent:

Ken Lee
Keith -

> After lots of searching I finally figured out why various parts of my
> views weren't aligning correctly.  Rectangles made based on a center
> point and an extent have their extents silently rounded to an integer
> multiple of 2 (via //) in the following methods:

I found the same problem when trying to draw concentric circles, since
Canvas>>ellipse: aRectangle takes a Rectangle, and I have been using the
same method to construct the Rectangle.

Being impatient, I put off trying to make those views. I'm grateful that
you figured it out.

- Ken


Reply | Threaded
Open this post in threaded view
|

Re: Rectangle class>>#center:extent:

Blair McGlashan
In reply to this post by Keith Alcock
Keith

You wrote in message news:[hidden email]...
> After lots of searching I finally figured out why various parts of my
> views weren't aligning correctly.  Rectangles made based on a center
> point and an extent have their extents silently rounded to an integer
> multiple of 2 (via //) in the following methods:

(x // 2) does not round to a x to an integer multiple of 2, it is integer
division by 2 with truncation toward negative infinity, e.g. 6//2 = 3.

>...
> I don't believe there is any requirement that the points or dimensions
> of a rectangle be integers at all, much less multiples of 2.

Dismissing the part about multiples of 2 (which isn't the case as explained
above), I at least partly agree with you. However its like it is because
that is the way it was originally defined. There may be errors in the
methods (or better ways of doing them) that introduce less error, so if
anybody spots any then please let us know.

>...Since
> these functions are probably used for centering windows and Windows
> doesn't like non-integer coordinates, I can imagine where the code
> originated.  However, the general Rectangle class is not the proper
> place for such a conversion I would like to request that it be
> (re)moved.

The implementation mostly originates from Smalltalk-80, and I think you will
find all Smalltalks implement Rectangle in a fairly standard way using
integer truncations in the same places, so there are compatibility issues at
stake.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Rectangle class>>#center:extent:

Keith Alcock
Blair,

OK, I was not completely correct in the description of the problem.  If
the extent is 7.8, then you get 7.8 // 2 = 3 as well, so that the origin
is 3 units to the left of center instead of 3.4 units.  The extent
remains 7.8, but at least for the purpose of calculating the origin, a
rounded value is effectively used.

This can be used to create some nice, but undesirable graphic effects.
Take a rectangle at the origin and increase the extent in a couple steps
to watch it move around:

center  extent  ->  left   right
  0       2.0        -1     +1.0
  0       2.4        -1     +1.4
  0       2.8        -1     +1.8
  0       3.2        -1     +2.2
  0       3.6        -1     +2.6
  0       4.0        -2     +2.0
  0       4.4        -2     +2.4

etc., and of course in two dimensions.

So, instead of expanding around the center, it expands right (and down)
first and suddenly makes a jump left (and up) before repeating.

Someone else pointed out that it is a problem if you want to create
concentric shapes.

I peeked into VW and see that it also has some use of // 2, although in
different places (and not in the constructor).  That Smalltalk-80 had it
just means that it is an old mistake in my estimation, but I understand
reluctance to change it.  My advice would be to avoid using the function
and maybe to deprecate it.

Keith


Blair McGlashan wrote:

>
> Keith
>
> You wrote in message news:[hidden email]...
> > After lots of searching I finally figured out why various parts of my
> > views weren't aligning correctly.  Rectangles made based on a center
> > point and an extent have their extents silently rounded to an integer
> > multiple of 2 (via //) in the following methods:
>
> (x // 2) does not round to a x to an integer multiple of 2, it is integer
> division by 2 with truncation toward negative infinity, e.g. 6//2 = 3.
>
> >...
> > I don't believe there is any requirement that the points or dimensions
> > of a rectangle be integers at all, much less multiples of 2.
>
> Dismissing the part about multiples of 2 (which isn't the case as explained
> above), I at least partly agree with you. However its like it is because
> that is the way it was originally defined. There may be errors in the
> methods (or better ways of doing them) that introduce less error, so if
> anybody spots any then please let us know.
>
> >...Since
> > these functions are probably used for centering windows and Windows
> > doesn't like non-integer coordinates, I can imagine where the code
> > originated.  However, the general Rectangle class is not the proper
> > place for such a conversion I would like to request that it be
> > (re)moved.
>
> The implementation mostly originates from Smalltalk-80, and I think you will
> find all Smalltalks implement Rectangle in a fairly standard way using
> integer truncations in the same places, so there are compatibility issues at
> stake.
>
> Regards
>
> Blair