问题
I know that whenever we want to apply a series of transform at once to a point, we have to specify the sequence in the opposite direction to what we want to perceive. If I want to translate(T) and then rotate(R) a point x we need to end with a concatenation matrix RT, then every point is transformed as (RT)x.
Apple Transform documentation shows that CGAffineTransform work as a transpose version of the above expression. i.e instead of transform a points as Ax for A being any transform matrix they do it as xB for B being the transpose of A.
Also CGAffineTransform.concatenating(T2) documentation state that it stack transforms to the right, ending in an transform matrix of the form as T1 * T2.
Now what are my concerns? If want a series of transformation that translate
(T) and then rotate
(R), I can call T.concatenating(R)
which result in a transform TR, then the points are transformed as xTR, it seem that the order must be respected, but actually I'm getting the wrong result(at least that's what i think), I expect the image A but getting B,
It seem that they are transforming points as TRx, but this contradict the documentation and also not match the result when you apply the transform TR to a point as CGPoint.applying(TR) which also is consistent with the order xTR.
why's that? there's something that I'm missing about how transforms works in iOS?
回答1:
If I'm not mistaken, your confusion lies not with order of operations, but with the rotate transformation. Rotation does not take place about the object's center, but about the origin of the frame, which remains fixed in place. When you rotate an object not centered at the frame's origin, it pivots around like the end of the hand of a clock. To achieve image A, you must
- Translate your object so that the point you wish to rotate it about (presumably its center) lies at the origin.
- Rotate the object.
- Translate it to the desired position.
回答2:
It's hard to see what the question is here, because you've already answered it. Basically, the order you must use when calling concatenating
is the opposite of the order you would use when chaining transformations. Thus for example:
v2.transform =
CGAffineTransform(rotationAngle: 45 * .pi/180).translatedBy(x: 100, y: 0)
In this screen shot, v2
is the green view, and started out where the purple view is:
If you wanted to do that with concatenating
, you'd say:
let r = CGAffineTransform(rotationAngle: 45 * .pi/180)
let t = CGAffineTransform(translationX:100, y:0)
v2.transform = t.concatenating(r) // not r.concatenating(t)
回答3:
let rotationAngle = CGFloat.pi / 4
let slidingLength : CGFloat = 50
let duration = 0.3
UIView.animate(withDuration: duration) { [weak self] in
self?.slidingView.transform = CGAffineTransform(rotationAngle: rotationAngle)
self?.slidingView.center.x += slidingLength
}
来源:https://stackoverflow.com/questions/49910034/cgaffinetransform-concatenation-appropriate-order-of-transformations