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.

Reply via email to