WindowingTransformation.st
author claus
Fri, 16 Jul 1993 11:42:20 +0200
changeset 0 48194c26a46c
child 2 b35336ab0de3
permissions -rw-r--r--
Initial revision
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
48194c26a46c Initial revision
claus
parents:
diff changeset
     1
"
48194c26a46c Initial revision
claus
parents:
diff changeset
     2
 COPYRIGHT (c) 1992 by Claus Gittinger
48194c26a46c Initial revision
claus
parents:
diff changeset
     3
              All Rights Reserved
48194c26a46c Initial revision
claus
parents:
diff changeset
     4
48194c26a46c Initial revision
claus
parents:
diff changeset
     5
 This software is furnished under a license and may be used
48194c26a46c Initial revision
claus
parents:
diff changeset
     6
 only in accordance with the terms of that license and with the
48194c26a46c Initial revision
claus
parents:
diff changeset
     7
 inclusion of the above copyright notice.   This software may not
48194c26a46c Initial revision
claus
parents:
diff changeset
     8
 be provided or otherwise made available to, or used by, any
48194c26a46c Initial revision
claus
parents:
diff changeset
     9
 other person.  No title to or ownership of the software is
48194c26a46c Initial revision
claus
parents:
diff changeset
    10
 hereby transferred.
48194c26a46c Initial revision
claus
parents:
diff changeset
    11
"
48194c26a46c Initial revision
claus
parents:
diff changeset
    12
48194c26a46c Initial revision
claus
parents:
diff changeset
    13
Object subclass: #WindowingTransformation
48194c26a46c Initial revision
claus
parents:
diff changeset
    14
        instanceVariableNames: 'scale translation'
48194c26a46c Initial revision
claus
parents:
diff changeset
    15
        classVariableNames: ''
48194c26a46c Initial revision
claus
parents:
diff changeset
    16
        poolDictionaries: ''
48194c26a46c Initial revision
claus
parents:
diff changeset
    17
        category: 'Graphics-Support'!
48194c26a46c Initial revision
claus
parents:
diff changeset
    18
48194c26a46c Initial revision
claus
parents:
diff changeset
    19
WindowingTransformation comment:'
48194c26a46c Initial revision
claus
parents:
diff changeset
    20
COPYRIGHT (c) 1992 by Claus Gittinger
48194c26a46c Initial revision
claus
parents:
diff changeset
    21
              All Rights Reserved
48194c26a46c Initial revision
claus
parents:
diff changeset
    22
48194c26a46c Initial revision
claus
parents:
diff changeset
    23
I represent the ability to perform transformations in 2-D space.
48194c26a46c Initial revision
claus
parents:
diff changeset
    24
48194c26a46c Initial revision
claus
parents:
diff changeset
    25
Instance variables are:
48194c26a46c Initial revision
claus
parents:
diff changeset
    26
scale           <Number> or <Point> representing a
48194c26a46c Initial revision
claus
parents:
diff changeset
    27
                                    linear scaling factor.
48194c26a46c Initial revision
claus
parents:
diff changeset
    28
translation     <Number> or <Point> representing a
48194c26a46c Initial revision
claus
parents:
diff changeset
    29
                                    translation in 2-D.
48194c26a46c Initial revision
claus
parents:
diff changeset
    30
48194c26a46c Initial revision
claus
parents:
diff changeset
    31
All 2-D objects are supposed to be able to be transformed using
48194c26a46c Initial revision
claus
parents:
diff changeset
    32
instances of me.  Instances of me can also be combined to form a
48194c26a46c Initial revision
claus
parents:
diff changeset
    33
single composite transformation.
48194c26a46c Initial revision
claus
parents:
diff changeset
    34
48194c26a46c Initial revision
claus
parents:
diff changeset
    35
%W% %E%
48194c26a46c Initial revision
claus
parents:
diff changeset
    36
48194c26a46c Initial revision
claus
parents:
diff changeset
    37
written summer 92 by claus
48194c26a46c Initial revision
claus
parents:
diff changeset
    38
'!
48194c26a46c Initial revision
claus
parents:
diff changeset
    39
48194c26a46c Initial revision
claus
parents:
diff changeset
    40
!WindowingTransformation methodsFor: 'accessing'!
48194c26a46c Initial revision
claus
parents:
diff changeset
    41
48194c26a46c Initial revision
claus
parents:
diff changeset
    42
scale
48194c26a46c Initial revision
claus
parents:
diff changeset
    43
    "return a copy of the Point that represents the
48194c26a46c Initial revision
claus
parents:
diff changeset
    44
     current scale of the receiver."
48194c26a46c Initial revision
claus
parents:
diff changeset
    45
48194c26a46c Initial revision
claus
parents:
diff changeset
    46
    scale == nil ifTrue:[
48194c26a46c Initial revision
claus
parents:
diff changeset
    47
        ^ Point x:1 y:1
48194c26a46c Initial revision
claus
parents:
diff changeset
    48
    ].
48194c26a46c Initial revision
claus
parents:
diff changeset
    49
    ^ scale copy
48194c26a46c Initial revision
claus
parents:
diff changeset
    50
!
48194c26a46c Initial revision
claus
parents:
diff changeset
    51
48194c26a46c Initial revision
claus
parents:
diff changeset
    52
scaleOfOne
48194c26a46c Initial revision
claus
parents:
diff changeset
    53
    "Set the scale of the receiver to the identity scale"
48194c26a46c Initial revision
claus
parents:
diff changeset
    54
48194c26a46c Initial revision
claus
parents:
diff changeset
    55
    scale := nil
48194c26a46c Initial revision
claus
parents:
diff changeset
    56
!
48194c26a46c Initial revision
claus
parents:
diff changeset
    57
48194c26a46c Initial revision
claus
parents:
diff changeset
    58
translation
48194c26a46c Initial revision
claus
parents:
diff changeset
    59
    "return a copy of the receiver's translation."
48194c26a46c Initial revision
claus
parents:
diff changeset
    60
48194c26a46c Initial revision
claus
parents:
diff changeset
    61
    ^ translation copy
48194c26a46c Initial revision
claus
parents:
diff changeset
    62
!
48194c26a46c Initial revision
claus
parents:
diff changeset
    63
48194c26a46c Initial revision
claus
parents:
diff changeset
    64
translation: aValue
48194c26a46c Initial revision
claus
parents:
diff changeset
    65
    "Set the receiver's translation to aValue."
48194c26a46c Initial revision
claus
parents:
diff changeset
    66
48194c26a46c Initial revision
claus
parents:
diff changeset
    67
    translation := aValue
48194c26a46c Initial revision
claus
parents:
diff changeset
    68
! !
48194c26a46c Initial revision
claus
parents:
diff changeset
    69
48194c26a46c Initial revision
claus
parents:
diff changeset
    70
!WindowingTransformation methodsFor: 'testing'!
48194c26a46c Initial revision
claus
parents:
diff changeset
    71
48194c26a46c Initial revision
claus
parents:
diff changeset
    72
noScale
48194c26a46c Initial revision
claus
parents:
diff changeset
    73
    "return true if the identity scale is in effect;
48194c26a46c Initial revision
claus
parents:
diff changeset
    74
         answer false, otherwise."
48194c26a46c Initial revision
claus
parents:
diff changeset
    75
48194c26a46c Initial revision
claus
parents:
diff changeset
    76
    ^ scale == nil
48194c26a46c Initial revision
claus
parents:
diff changeset
    77
! !
48194c26a46c Initial revision
claus
parents:
diff changeset
    78
48194c26a46c Initial revision
claus
parents:
diff changeset
    79
!WindowingTransformation methodsFor: 'applying transform'!
48194c26a46c Initial revision
claus
parents:
diff changeset
    80
48194c26a46c Initial revision
claus
parents:
diff changeset
    81
applyInverseTo:anObject 
48194c26a46c Initial revision
claus
parents:
diff changeset
    82
    "Apply the inverse of the receiver to anObject
48194c26a46c Initial revision
claus
parents:
diff changeset
    83
     and answer the result."
48194c26a46c Initial revision
claus
parents:
diff changeset
    84
48194c26a46c Initial revision
claus
parents:
diff changeset
    85
    |transformedObject|
48194c26a46c Initial revision
claus
parents:
diff changeset
    86
48194c26a46c Initial revision
claus
parents:
diff changeset
    87
    transformedObject := anObject translateBy:(self inverseTranslation).
48194c26a46c Initial revision
claus
parents:
diff changeset
    88
    scale == nil ifFalse:[
48194c26a46c Initial revision
claus
parents:
diff changeset
    89
        transformedObject := transformedObject scaleBy:(self inverseScale)
48194c26a46c Initial revision
claus
parents:
diff changeset
    90
    ].
48194c26a46c Initial revision
claus
parents:
diff changeset
    91
    ^ transformedObject
48194c26a46c Initial revision
claus
parents:
diff changeset
    92
!
48194c26a46c Initial revision
claus
parents:
diff changeset
    93
48194c26a46c Initial revision
claus
parents:
diff changeset
    94
applyTo:anObject 
48194c26a46c Initial revision
claus
parents:
diff changeset
    95
    "Apply the receiver to anObject and answer the result."
48194c26a46c Initial revision
claus
parents:
diff changeset
    96
48194c26a46c Initial revision
claus
parents:
diff changeset
    97
    |transformedObject|
48194c26a46c Initial revision
claus
parents:
diff changeset
    98
48194c26a46c Initial revision
claus
parents:
diff changeset
    99
    scale == nil ifTrue:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   100
        transformedObject := anObject
48194c26a46c Initial revision
claus
parents:
diff changeset
   101
    ] ifFalse:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   102
        transformedObject := anObject scaleBy:scale
48194c26a46c Initial revision
claus
parents:
diff changeset
   103
    ].
48194c26a46c Initial revision
claus
parents:
diff changeset
   104
    transformedObject := transformedObject translateBy:translation.
48194c26a46c Initial revision
claus
parents:
diff changeset
   105
    ^ transformedObject
48194c26a46c Initial revision
claus
parents:
diff changeset
   106
!
48194c26a46c Initial revision
claus
parents:
diff changeset
   107
48194c26a46c Initial revision
claus
parents:
diff changeset
   108
compose:aTransformation 
48194c26a46c Initial revision
claus
parents:
diff changeset
   109
    "return a new WindowingTransformation that is the
48194c26a46c Initial revision
claus
parents:
diff changeset
   110
     composition of the receiver and aTransformation.
48194c26a46c Initial revision
claus
parents:
diff changeset
   111
     The effect of applying the resulting WindowingTransformation
48194c26a46c Initial revision
claus
parents:
diff changeset
   112
     to an object is the same as that of first applying
48194c26a46c Initial revision
claus
parents:
diff changeset
   113
     aTransformation to the object and then applying the 
48194c26a46c Initial revision
claus
parents:
diff changeset
   114
     receiver to its result."
48194c26a46c Initial revision
claus
parents:
diff changeset
   115
48194c26a46c Initial revision
claus
parents:
diff changeset
   116
    |aTransformationScale newScale newTranslation|
48194c26a46c Initial revision
claus
parents:
diff changeset
   117
48194c26a46c Initial revision
claus
parents:
diff changeset
   118
    aTransformationScale := aTransformation scale.
48194c26a46c Initial revision
claus
parents:
diff changeset
   119
    scale == nil ifTrue:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   120
        aTransformation noScale ifTrue:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   121
            newScale := nil
48194c26a46c Initial revision
claus
parents:
diff changeset
   122
        ] ifFalse:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   123
            newScale := aTransformationScale
48194c26a46c Initial revision
claus
parents:
diff changeset
   124
        ].
48194c26a46c Initial revision
claus
parents:
diff changeset
   125
        newTranslation := translation + aTransformation translation
48194c26a46c Initial revision
claus
parents:
diff changeset
   126
    ] ifFalse:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   127
        aTransformation noScale ifTrue:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   128
            newScale := scale
48194c26a46c Initial revision
claus
parents:
diff changeset
   129
        ] ifFalse:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   130
            newScale := scale * aTransformationScale
48194c26a46c Initial revision
claus
parents:
diff changeset
   131
        ].
48194c26a46c Initial revision
claus
parents:
diff changeset
   132
        newTranslation := translation
48194c26a46c Initial revision
claus
parents:
diff changeset
   133
                          + (scale * aTransformation translation)
48194c26a46c Initial revision
claus
parents:
diff changeset
   134
    ].
48194c26a46c Initial revision
claus
parents:
diff changeset
   135
    ^ WindowingTransformation scale:newScale
48194c26a46c Initial revision
claus
parents:
diff changeset
   136
                        translation:newTranslation
48194c26a46c Initial revision
claus
parents:
diff changeset
   137
! !
48194c26a46c Initial revision
claus
parents:
diff changeset
   138
48194c26a46c Initial revision
claus
parents:
diff changeset
   139
!WindowingTransformation methodsFor: 'transforming'!
48194c26a46c Initial revision
claus
parents:
diff changeset
   140
48194c26a46c Initial revision
claus
parents:
diff changeset
   141
scaleBy:aScale 
48194c26a46c Initial revision
claus
parents:
diff changeset
   142
    "return a new WindowingTransformation with the scale and translation of 
48194c26a46c Initial revision
claus
parents:
diff changeset
   143
     the receiver both scaled by aScale."
48194c26a46c Initial revision
claus
parents:
diff changeset
   144
48194c26a46c Initial revision
claus
parents:
diff changeset
   145
    |checkedScale newScale newTranslation|
48194c26a46c Initial revision
claus
parents:
diff changeset
   146
48194c26a46c Initial revision
claus
parents:
diff changeset
   147
    aScale == nil ifTrue:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   148
        newScale := scale.
48194c26a46c Initial revision
claus
parents:
diff changeset
   149
        newTranslation := translation
48194c26a46c Initial revision
claus
parents:
diff changeset
   150
    ] ifFalse:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   151
        checkedScale := self checkScale:aScale.
48194c26a46c Initial revision
claus
parents:
diff changeset
   152
        scale == nil ifTrue:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   153
            newScale := checkedScale
48194c26a46c Initial revision
claus
parents:
diff changeset
   154
        ] ifFalse:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   155
            newScale := scale * checkedScale
48194c26a46c Initial revision
claus
parents:
diff changeset
   156
        ].
48194c26a46c Initial revision
claus
parents:
diff changeset
   157
        newTranslation := checkedScale * translation
48194c26a46c Initial revision
claus
parents:
diff changeset
   158
    ].
48194c26a46c Initial revision
claus
parents:
diff changeset
   159
    ^ WindowingTransformation scale:newScale
48194c26a46c Initial revision
claus
parents:
diff changeset
   160
                        translation:newTranslation
48194c26a46c Initial revision
claus
parents:
diff changeset
   161
!
48194c26a46c Initial revision
claus
parents:
diff changeset
   162
48194c26a46c Initial revision
claus
parents:
diff changeset
   163
translateBy:aPoint 
48194c26a46c Initial revision
claus
parents:
diff changeset
   164
    "return a new WindowingTransformation with the same scale and 
48194c26a46c Initial revision
claus
parents:
diff changeset
   165
     rotations as the receiver and with a translation of the current 
48194c26a46c Initial revision
claus
parents:
diff changeset
   166
     translation plus aPoint."
48194c26a46c Initial revision
claus
parents:
diff changeset
   167
48194c26a46c Initial revision
claus
parents:
diff changeset
   168
    ^ WindowingTransformation scale:scale
48194c26a46c Initial revision
claus
parents:
diff changeset
   169
                        translation:(translation + aPoint)
48194c26a46c Initial revision
claus
parents:
diff changeset
   170
! !
48194c26a46c Initial revision
claus
parents:
diff changeset
   171
48194c26a46c Initial revision
claus
parents:
diff changeset
   172
!WindowingTransformation methodsFor: 'printing'!
48194c26a46c Initial revision
claus
parents:
diff changeset
   173
48194c26a46c Initial revision
claus
parents:
diff changeset
   174
printString
48194c26a46c Initial revision
claus
parents:
diff changeset
   175
    ^ (self class name, ' scale: ', scale printString,
48194c26a46c Initial revision
claus
parents:
diff changeset
   176
                  ' translation: ', translation printString)
48194c26a46c Initial revision
claus
parents:
diff changeset
   177
! !
48194c26a46c Initial revision
claus
parents:
diff changeset
   178
48194c26a46c Initial revision
claus
parents:
diff changeset
   179
!WindowingTransformation methodsFor: 'private'!
48194c26a46c Initial revision
claus
parents:
diff changeset
   180
48194c26a46c Initial revision
claus
parents:
diff changeset
   181
checkScale:aScale
48194c26a46c Initial revision
claus
parents:
diff changeset
   182
    "Converts aScale to the internal format of a floating-point Point."
48194c26a46c Initial revision
claus
parents:
diff changeset
   183
48194c26a46c Initial revision
claus
parents:
diff changeset
   184
    |checkedScale|
48194c26a46c Initial revision
claus
parents:
diff changeset
   185
48194c26a46c Initial revision
claus
parents:
diff changeset
   186
    checkedScale := aScale asPoint.
48194c26a46c Initial revision
claus
parents:
diff changeset
   187
    ^ Point x:checkedScale x asFloat
48194c26a46c Initial revision
claus
parents:
diff changeset
   188
            y:checkedScale y asFloat
48194c26a46c Initial revision
claus
parents:
diff changeset
   189
!
48194c26a46c Initial revision
claus
parents:
diff changeset
   190
48194c26a46c Initial revision
claus
parents:
diff changeset
   191
inverseScale
48194c26a46c Initial revision
claus
parents:
diff changeset
   192
    "return with a Point representing the inverse of my
48194c26a46c Initial revision
claus
parents:
diff changeset
   193
     scale."
48194c26a46c Initial revision
claus
parents:
diff changeset
   194
48194c26a46c Initial revision
claus
parents:
diff changeset
   195
    |newScale|
48194c26a46c Initial revision
claus
parents:
diff changeset
   196
48194c26a46c Initial revision
claus
parents:
diff changeset
   197
    newScale := self checkScale:scale.
48194c26a46c Initial revision
claus
parents:
diff changeset
   198
    ^ Point x:(1.0 / newScale x)
48194c26a46c Initial revision
claus
parents:
diff changeset
   199
            y:(1.0 / newScale y)
48194c26a46c Initial revision
claus
parents:
diff changeset
   200
!
48194c26a46c Initial revision
claus
parents:
diff changeset
   201
48194c26a46c Initial revision
claus
parents:
diff changeset
   202
inverseTranslation
48194c26a46c Initial revision
claus
parents:
diff changeset
   203
    "return with a Point representing the inverse of my
48194c26a46c Initial revision
claus
parents:
diff changeset
   204
     translation."
48194c26a46c Initial revision
claus
parents:
diff changeset
   205
48194c26a46c Initial revision
claus
parents:
diff changeset
   206
    |trans|
48194c26a46c Initial revision
claus
parents:
diff changeset
   207
48194c26a46c Initial revision
claus
parents:
diff changeset
   208
    trans := translation asPoint.
48194c26a46c Initial revision
claus
parents:
diff changeset
   209
    ^ Point x:trans x negated
48194c26a46c Initial revision
claus
parents:
diff changeset
   210
            y:trans y negated
48194c26a46c Initial revision
claus
parents:
diff changeset
   211
!
48194c26a46c Initial revision
claus
parents:
diff changeset
   212
48194c26a46c Initial revision
claus
parents:
diff changeset
   213
setScale:aScale translation:aTranslation
48194c26a46c Initial revision
claus
parents:
diff changeset
   214
    "Sets the scale to aScale and the translation to aTranslation."
48194c26a46c Initial revision
claus
parents:
diff changeset
   215
48194c26a46c Initial revision
claus
parents:
diff changeset
   216
    scale := aScale.
48194c26a46c Initial revision
claus
parents:
diff changeset
   217
    translation := aTranslation
48194c26a46c Initial revision
claus
parents:
diff changeset
   218
! !
48194c26a46c Initial revision
claus
parents:
diff changeset
   219
48194c26a46c Initial revision
claus
parents:
diff changeset
   220
!WindowingTransformation class methodsFor: 'instance creation'!
48194c26a46c Initial revision
claus
parents:
diff changeset
   221
48194c26a46c Initial revision
claus
parents:
diff changeset
   222
identity
48194c26a46c Initial revision
claus
parents:
diff changeset
   223
    "returns a windowing transformation with no scaling (nil) 
48194c26a46c Initial revision
claus
parents:
diff changeset
   224
     and no translation (0@0)."
48194c26a46c Initial revision
claus
parents:
diff changeset
   225
48194c26a46c Initial revision
claus
parents:
diff changeset
   226
    ^ self new setScale:nil
48194c26a46c Initial revision
claus
parents:
diff changeset
   227
            translation:(Point x:0.0 y:0.0)
48194c26a46c Initial revision
claus
parents:
diff changeset
   228
!
48194c26a46c Initial revision
claus
parents:
diff changeset
   229
48194c26a46c Initial revision
claus
parents:
diff changeset
   230
scale:aScale translation:aTranslation 
48194c26a46c Initial revision
claus
parents:
diff changeset
   231
    "returns a windowing transformation with a scale factor of  
48194c26a46c Initial revision
claus
parents:
diff changeset
   232
     aScale and a translation offset of aTranslation."
48194c26a46c Initial revision
claus
parents:
diff changeset
   233
48194c26a46c Initial revision
claus
parents:
diff changeset
   234
    ^ self new setScale:aScale
48194c26a46c Initial revision
claus
parents:
diff changeset
   235
            translation:aTranslation
48194c26a46c Initial revision
claus
parents:
diff changeset
   236
!
48194c26a46c Initial revision
claus
parents:
diff changeset
   237
48194c26a46c Initial revision
claus
parents:
diff changeset
   238
window:sourceRectangle viewport:destinationRectangle 
48194c26a46c Initial revision
claus
parents:
diff changeset
   239
    "returns a windowing transformation with a scale and
48194c26a46c Initial revision
claus
parents:
diff changeset
   240
     translation computed from sourceRectangle and destinationRectangle.
48194c26a46c Initial revision
claus
parents:
diff changeset
   241
     The scale and transformation are computed such that sourceRectangle
48194c26a46c Initial revision
claus
parents:
diff changeset
   242
     is transformed to destinationRectangle."
48194c26a46c Initial revision
claus
parents:
diff changeset
   243
48194c26a46c Initial revision
claus
parents:
diff changeset
   244
    |sX sY tX tY newScale|
48194c26a46c Initial revision
claus
parents:
diff changeset
   245
    sX := destinationRectangle width / sourceRectangle width.
48194c26a46c Initial revision
claus
parents:
diff changeset
   246
    sY := destinationRectangle height / sourceRectangle height.
48194c26a46c Initial revision
claus
parents:
diff changeset
   247
    tX := destinationRectangle left - sourceRectangle left.
48194c26a46c Initial revision
claus
parents:
diff changeset
   248
    tY := destinationRectangle top - sourceRectangle top.
48194c26a46c Initial revision
claus
parents:
diff changeset
   249
    ((sX = 1.0) and:[sY = 1.0]) ifTrue:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   250
        newScale := nil
48194c26a46c Initial revision
claus
parents:
diff changeset
   251
    ] ifFalse:[
48194c26a46c Initial revision
claus
parents:
diff changeset
   252
        newScale := Point x:sX y:sY
48194c26a46c Initial revision
claus
parents:
diff changeset
   253
    ].
48194c26a46c Initial revision
claus
parents:
diff changeset
   254
    ^ self new setScale:newScale
48194c26a46c Initial revision
claus
parents:
diff changeset
   255
            translation:(Point x:tX y:tY)
48194c26a46c Initial revision
claus
parents:
diff changeset
   256
! !