This service method is called by the
.mag() methods to analyze the transform into its
component parts. The first time it is called, it stores
the three components into attributes
.__mag. Succeeding calls do nothing because
the values don't change.
# - - - X f o r m . _ _ a n a l y z e def __analyze(self): '''Compute self's net translation, rotation, and scaling. [ if self.__offset is None -> self.__offset := net translation of self as a Pt self.__angle := net rotation of self self.__mag := net uniform scaling of self else -> I ] '''
The constructor initializes
None, so if that attribute no longer has
that value, this method has already been called, and
the results have already been memoized.
#-- 1 -- if self.__offset is not None: return
To analyze the effects of a transform, we apply it to the
origin and to
self.UNIT, which is the
point at a distance 1.0 along the line
The translation component is the amount that the origin moves.
Because the line from
self.UNIT has bearing 45° by
definition, the rotational component of the transform
is the bearing of that line after transformation,
minus 45°, normalized.
Because the distance from
self.UNIT has length 1, the uniform
scaling component of the transform is the distance
between those points after their transformation.
#-- 2 -- oPrime = self.apply ( self.ORIGIN ) uPrime = self.apply ( self.UNIT ) #-- 3 -- # [ self.__offset := distance from origin to oPrime # self.__angle := (bearing from oPrime to uPrime) - # RAD_45, normalized # self.__mag := distance from oPrime to uPrime ] self.__offset = Pt ( oPrime.xy() ) self.__angle = normAngle(oPrime.bearing ( uPrime ) - RAD_45) self.__mag = oPrime.dist ( uPrime )