2

UIView'sカスタムで複数のカスタムを作成していますUIView。カスタム サブビューの作成は問題ありません。それらは次のようになります。

ここに画像の説明を入力

draw メソッドは非常に簡単です。

[[UIColor brownColor] set];

CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx,
                      5.0f);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, 0.0f, 0.0f);
CGContextAddLineToPoint(ctx, 100.0f, 0.0);
CGContextAddLineToPoint(ctx, 130.0f, 25.0f);
CGContextAddLineToPoint(ctx, 100.0f, 50.0f);
CGContextAddLineToPoint(ctx, 0.0f, 50.0f);
CGContextClosePath(ctx);
CGContextStrokePath(ctx);
[super drawRect:rect];

スーパー ビューに追加するのも非常に簡単です。

    ITContextFigure *view = [[ITContextFigure alloc] initWithFrame:CGRectMake(location.x, location.y, 135.0f, 50.0f)];
    [view setBackgroundColor:[UIColor yellowColor]];
    [self addSubview:view];

だから私の質問は:

1)一方が他方と重なったことをどのように検出できますか?

私はこの解決策を見ました:

if (CGRectContainsRect([myImageView1 frame], [myImageView2 frame])) {
        NSLog(@"Overlaped, it's working!");
}

しかし、私が複数の を持っている場合UIViews、 を実行してforすべてのsuper viewサブビューをチェックすることは、私にとって良い解決策ではないようです。

2) この場合、どうすればよいでしょうか?

ここに画像の説明を入力

私の主な目標は、これがいつ発生するかを検出することです。

ここに画像の説明を入力


アップデート 1.0

よりエレガントな方法がないため、ここに示されていることを試してみましょう。私がそれを達成できれば、誰かがそれを必要とするなら、コードを Github に投稿します。

4

1 に答える 1

3

データを巧みに並べ替えることで、必要な衝突検出の数を大幅に減らすことができます (これらはスキャン ラインまたはシープ ライン アルゴリズムと呼ばれます)。この手法を状況に適用する方法の概要を次に示します。

サブビューを y の昇順の配列に並べ替えます。2 つのサブビューが同じ y を共有している場合、x の昇順に並べ替えます。これは非アクティブ リストであり、アルゴリズムへの主要な入力を形成します。

アルゴリズムは次のように進みます。

  1. 非アクティブなサブビューがある場合は、active_y. これは、非アクティブ リストの最初のサブビューの y 座標です。

  2. 行上に原点があるすべてのサブビューをactive_y作業リストに移動し、x の昇順で並べ替えます。これがアクティブリストです。

  3. 各サブビューと、リスト上の後続のサブビューとのアクティブ リスト衝突テストを実行します。leftリストに 2 つのインデックスを使用してこれを行います (それらを と と呼びましょうright)。right交差できないサブビューが表示されるとすぐに、インデックスleftを進めることができます。left

  4. 衝突検出を行っている間、サブビューが完全に下にあるかどうかも確認しますactive_y。削除したら、アクティブ リストから削除する必要があります。

非アクティブ リストのすべてのサブビューが消費され、アクティブ リストの最終実行が完了すると、アルゴリズムは完了します。

このアルゴリズムは、実行する必要がある衝突検出の数を大幅に削減し、おおよそ O(n log n) ですが、衝突検出自体を簡素化することもできます。

アクティブ リストは左から右にソートされるため、検出ルーチンを実行しているとき、どれが左にあり、どれが右にあるかを常に知ることができます。したがって、たとえば、例の矢印の形状を比較する場合、右の形状の左端の 2 つの頂点が左の形状内にあるかどうかを確認するだけで済みます。役に立つかもしれませんCGPathContainsPoint

扱っている個別の形状の数が増えた場合は、衝突検出をスキャン ライン アルゴリズム自体にプッシュすることを検討する必要があるかもしれません。これは少しトリッキーですが、基本的に、サブビュー ポインターを保持するリストの代わりに、形状を構成する線分 (水平のものを除く) を保持します。

于 2012-07-16T23:49:15.217 に答える