3

と同等のCATransform3Dを作成するにはどうすればよいですか?

CGPoint CGPointApplyAffineTransform(CGPoint point, CGAffineTransform t)
CGSize CGSizeApplyAffineTransform(CGSize size, CGAffineTransform t);
CGRect CGRectApplyAffineTransform(CGRect rect, CGAffineTransform t);

4

2 に答える 2

3

これは機能しますが、もちろん、内部で何が起こっているのかを知る方がはるかに良い-[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;
}

簡単な単体テストhttps://gist.github.com/hfossli/5130975

于 2013-03-10T23:13:11.270 に答える
3

さて、次のようなもの:

- (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(オブジェクトに変換せずに、またはその逆)でより良いでしょうが、私はただアイデアを示したかっただけです。

CGPointxとyのみで構成されており、「回答」ではそれらがまったくカウントされないため、Z座標はありません。

「アンカーポイント」パラメータとは何ですか?アンカーポイントとは、いくつかの追加の行列乗算を意味します。フィギュアを移動してアンカーポイントをに表示し(0, 0, 0)、変換を適用して、フィギュアを同じ距離だけ戻します。

親変換パラメータ?ここでも、2つの4x4行列を正しい順序で乗算する必要があります。

そしてもちろん、あなたはあなたの質問の残りにさえ答えません。

CGRect CGRectApplyAffineTransform(CGRect rect, CGAffineTransform t);

1つのrectは4ポイントを意味します。これらの各ポイントに変換を適用する必要があります。

CGSize CGSizeApplyAffineTransform(CGSize size, CGAffineTransform t);

のための変換CGSize?2次元でポイントがまったく指定されていない状態でCGSize、3Dに変換しますか?CGSizeたとえば、回転がサイズに影響を与える可能性があり、この回転を実行するための最初のアンカーポイントがわからないため、すべての変数がない場合に問題を解決しようとします。

于 2015-07-28T08:47:18.230 に答える