Thank you Igor, I understand and I agree. Just can you clarify one think. Maybe I use it wrong. Right now in Roassal2/Trachel a shape has instance variable called matrix which is an AthensAffineTransform object. And if someone calls translateBy:, or scaleBy:, etc. I call the appropriate method on AthensAffineTransform. Do you say, that I should rather have instance variables position, rotation, and scale? Do I understand well? I thought it is better (faster) to keep the matrix and in #drawOn: only call #multiplyBy:.
And another question. Right now a rectangle is drawn like this: -=-=-=-=- computePath canvas ifNil: [ ^ self ]. path := self athensCanvas createPath: [ :builder | builder absolute; moveTo: rectangle topLeft; lineTo: rectangle topRight; lineTo: rectangle bottomRight; lineTo: rectangle bottomLeft; lineTo: rectangle topLeft. ] -=-=-=-=- I do not see a method which draws rectangle directly. This example shows there is a direct support for rectangle drawing. Am I right we do not have that support in Athens? Is there a reason for it? Thank you, Juraj El 11-04-2014, a las 13:29, Igor Stasenko <siguc...@gmail.com> escribió: > > > > On 11 April 2014 17:41, Juraj Kubelka <juraj.kube...@gmail.com> wrote: > Hi, > > We are integrating Athens transformation to Roassal2/Trachel and I have > reached an issue. > > In drawing code I use something like this: > -=-=-=- > athensCanvas pathTransform > restoreAfter: [ > athensCanvas pathTransform > multiplyBy: matrix; “an instance of > AthensAffineTransform" > athensCanvas > setPaint: color; > drawShape: self path. > -=-=-=- > > I have a problem, that sometimes it crashes because it expects a float value > (I understand why). I suppose I do not have to keep float values in > AthensAffineTransform object. My suggestion is to ensure float values where > it is expected. For example the method #loadAffineTransform could be like > this: > > -=-=-=- > AthensCairoMatrix>>loadAffineTransform: m > self > initx: m x asFloat > y: m y asFloat > sx: m sx asFloat > sy: m sy asFloat > shx: m shx asFloat > shy: m shy asFloat > -=-=-=- > > > Which will mean 6 extra #asFloat message sends, even if they're already > floats or ints but not Fractions (and in 99% of cases they are, so you will > slow down everything for the sake of 1%). > I prefer that user supplies already prepared data, so it don't have to be > implicitly converted since it takes extra CPU cycles, which can be spent > somewhere else. > > But yes, it needs to be ensured, but at different place: > where you building that AthensAffineTransform > > AthensAffineTransform>>sx: number > sx := number > =>>> > AthensAffineTransform>>sx: number > sx := number asFloat > .. (and for the rest of accessors) > > like that it will ensure that AthensAffineTransform always stores floats, > which i'm not really like because integers is perfectly fine too.. its all > about Fractions. > > > Right now I have to do that transformation myself whenever I use Athens > objects. I see it error prone and I do not see it obvious. > > On other hand I do not want to keep float values in my AthensAffineTransform, > because if user do #scaleBy: 0.7 and then #scaleBy: (1/0.7) I want to get the > same original value. Otherwise the image could change its size. > > > On your place i'd better forget about it. That's impossible when you dealing > with floating point values.. and multiple matrix operations. > Unless you explicitly control it by yourself, but that certainly should be > outside of AthensAffineTransform/Athens. > > The same change could be for other methods in AthensCairoMatrix. > > > Again, that would mean dozens of extra message sends at every single place, > whether it needed or not.. > Like: > AthensCairoMatrix>>translateX: px Y: py > > needs to be replaced with: > > ^ self primTranslateX: px asFloat Y: py asFloat > > instead of direct call, plus adding #primTranslateX:Y: method, of course. > > Do you really want to pay a price of 50% less performance (or more) in > exchange of "i don't wanna think what i passing to it"? > Because apparently, you always need to think what you passing - one cannot > just pass a random object to some method and expect it to work, isn't? > > Because i don't. All you need is to avoid using Fractions.. because integers > or floats is perfectly fine. > Fraction created only if you use division on integer.. so all you need to do > is to ensure the result of division is float: > > (x/y) asFloat. > > What do you think? > > I am biased towards having better performance, even at cost of inconvenience, > where at some places i have to ensure i need to pass correct value(s). > > > Juraj > > -- > Best regards, > Igor Stasenko.