我怎样才能写 CATransform3D 等效于
CGPoint CGPointApplyAffineTransform(CGPoint point, CGAffineTransform t)
CGSize CGSizeApplyAffineTransform(CGSize size, CGAffineTransform t);
CGRect CGRectApplyAffineTransform(CGRect rect, CGAffineTransform t);
?
我怎样才能写 CATransform3D 等效于
CGPoint CGPointApplyAffineTransform(CGPoint point, CGAffineTransform t)
CGSize CGSizeApplyAffineTransform(CGSize size, CGAffineTransform t);
CGRect CGRectApplyAffineTransform(CGRect rect, CGAffineTransform t);
?
这行得通,但是知道里面发生了什么当然会好得多-[CALayer convertPoint:toLayer:]
!
CGPoint CGPointApplyCATransform3D(CGPoint point, CATransform3D transform, CGPoint anchorPoint, CATransform3D parentSublayerTransform)
{
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static CALayer *sublayer, *layer;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sublayer = [CALayer layer];
layer = [CALayer layer];
[layer addSublayer:sublayer];
});
if(pthread_mutex_lock(&mtx))
{
[NSException raise:NSInternalInconsistencyException format:@"pthread_mutex_lock failed"];
}
layer.sublayerTransform = parentSublayerTransform;
sublayer.transform = transform;
sublayer.anchorPoint = anchorPoint;
CGPoint retval = [sublayer convertPoint:point toLayer:layer];
if(pthread_mutex_unlock(&mtx) != 0)
{
[NSException raise:NSInternalInconsistencyException format:@"pthread_mutex_unlock failed"];
}
return retval;
}
好的,类似于以下内容:
- (CGPoint)convertPoint:(CGPoint)p withTransform:(CATransform3D)t {
NSArray *m1 = @[@(p.x), @(p.y), @(0), @(1)];
NSMutableArray *m2 = [NSMutableArray array];
[m2 addObject:@[@(t.m11), @(t.m12), @(t.m13), @(t.m14)]];
[m2 addObject:@[@(t.m21), @(t.m22), @(t.m23), @(t.m24)]];
[m2 addObject:@[@(t.m31), @(t.m32), @(t.m33), @(t.m34)]];
[m2 addObject:@[@(t.m41), @(t.m42), @(t.m43), @(t.m44)]];
NSMutableArray *result = [NSMutableArray array];
for (int i = 0; i < 2; i++) {
double k = 0;
for (int j = 0; j < 4; j++) {
k += [m1[j] doubleValue] * [m2[j][i] doubleValue];
}
[result addObject:@(k)];
}
return CGPointMake([result[0] doubleValue], [result[1] doubleValue]);
}
没有异常,没有互斥锁在多线程上阻塞当前线程,没有额外的层,也没有等待这些层被绘制。
适用于大多数变换,例如平移、旋转、缩放及其组合。用Objective C编写,在纯C中会更好(不转换为对象,反之亦然),但我只是想展示一个想法。
没有 Z 坐标,因为CGPoint
仅由 x 和 y 组成,而您的“答案”根本不计算它们。
什么是“锚点”参数?锚点意味着一些额外的矩阵乘法 - 您移动图形以使您的锚点出现在 中(0, 0, 0)
,应用变换并将图形向后移动相同的距离。
父变换参数?同样,您只需要以正确的顺序将两个 4x4 矩阵相乘。
当然,你甚至不回答剩下的问题。
CGRect CGRectApplyAffineTransform(CGRect rect, CGAffineTransform t);
一个矩形意味着 4 个点。您只需要对这些点中的每一个应用变换。
CGSize CGSizeApplyAffineTransform(CGSize size, CGAffineTransform t);
变换为CGSize
? CGSize
在 3D 中转换,而CGSize
有 2 个维度并且根本没有指定点?当您没有所有变量时,您只是尝试解决问题,因为例如旋转可能会影响大小并且您不知道执行此旋转的初始锚点。