6

円の中に 12 個のオブジェクトを配置して、それぞれが反時計回りの隣のオブジェクトと重なるようにしようとしています。

このようなもの:

ここに画像の説明を入力

問題は、描画順序だけに頼ると、そのうちの 1 つが常に完全に上に表示されることです。この場合、12 時の位置にある赤いものです。

使ってみました

    {
        GlowButton* G = glowButton[ 0 ];

        float theta = 0.3;
        G.layer.transform = CATransform3DMakeRotation( theta, 0, 1, 0 );
    }

垂直軸を中心に回転させて、片側を隣の側の後ろに押し込もうとしていますが、これは機能していません。

これは、コア アニメーションがデプス テストをサポートしていないためだと言われています。

GLに侵入せずにこれを行う方法はありますか?

4

2 に答える 2

6

この問題を回避するには、次の 2 つの方法が考えられます。

  1. 各オブジェクトを半分に分割します。最初に隣接オブジェクトの背後にある半分を描画し、次に隣接オブジェクトの上に半分を描画します。

  2. クリッピング領域を使用して、2 つのステップで円を描きます。最初のクリッピング領域は、描画を画像の左半分に制限します。2 番目のクリッピング領域は、右半分に制限されています。毎回、すべてのオブジェクトを描画します。ただし、下部または上部の要素から開始する必要があります。

Core Animation で何をしているのかよくわからないので、アプローチの 1 つがより適しているか、何らかの適応が必要になる可能性があります。

于 2011-08-30T13:59:45.353 に答える
4

私はこれで完全に機能しています。GLに行く必要がなかったので、とても安心しています。

ここに画像の説明を入力

私は基本的に、最初の (赤 -- 12 時の位置にある) 宝石を、右半分だけが見えるようにマスクで描画します。

そして残りの11枚を描きます。

次に、最初のものをもう一度描きます。今回は、マスクを左半分のみを表示するように設定します。

    for( int i = 0; i <= 12; i++ )
    {
        for ( int dullGlow = 0; dullGlow <= 1; dullGlow++ )
        {
            BOOL isDull = ( dullGlow == 0 ) ? YES : NO;

            CALayer* L = [CALayer layer];

            CGImageRef dullImage = [ButtonImages dullImage: i % 12];
            CGImageRef glowImage = [ButtonImages glowImage: i % 12];

            L.contents = (id) ( isDull ? dullImage : glowImage );

            L.bounds = CGRectMake( 0, 0, buttonSize, buttonSize ); 

            L.opacity = ( isDull ? 1.0 : 0.0 );

            if( i == 0  ||  i == 12 )
            {
                CGFloat halfSize = buttonSize / 2.0;

                CGRect keepLeftHalf = CGRectMake( 0, 0, 
                                                 halfSize, buttonSize );

                CGRect keepRightHalf = CGRectMake( halfSize,  0, 
                                                  halfSize, buttonSize );

                CALayer* maskLayer = [CALayer layer];
                maskLayer.frame = ( i == 0 ) ? keepRightHalf : keepLeftHalf;
                maskLayer.backgroundColor = [UIColor greenColor].CGColor;

                maskLayer.edgeAntialiasingMask = 0x0;

                [L setMask: maskLayer];
            }

            [self.layer addSublayer: L];

            layers[ dullGlow ] [ i ] = L;

        } // dullGlow

    } // i

edgeAntialiasingMask の 4 つの最下位ビットを、4 つのエッジすべてでアンチエイリアシングの 0 項に設定します。この行がないと、継ぎ目ができていました。

マスキング プロセスのメカニズムを誰かが説明できれば非常にありがたいです。正しい結果が得られましたが、試行錯誤を繰り返しました。

マスクが (不透明な) 緑に設定されており、マスクされた領域が表示されていることに注意してください。つまり、最初のパスでは、緑の四角形が画像の右半分を覆っており、表示されるのはこの愛です。

ピクセルごとに、レイヤーピクセルRGBAにマスクピクセルのアルファ値を掛けていると推測しています

于 2011-08-31T07:33:06.970 に答える