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 |
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 |
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 |
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 |
Free forum by Nabble | Edit this page |