4

MKPolygon が MKCircle と交差するかどうかをテストするためのガイダンスを探しています。現在私は使用しています:

if ([circle intersectsMapRect:[poly boundingMapRect]]) {
                    //they do intersect
   }

私は、これが不正確な結果を返すだけであることがわかりました.b / cは、円の周りに長方形を描画するため、そうでないはずの交点が得られます.

トピックを検索すると、Chad Saxon のポリゴン ポリゴン インターセクション プロジェクトにたどり着きました。これは、MKCircle を多角形に何らかの方法で変換できる場合に役立ちます。これは可能ですが、最終的にはこれがこれを解決するための回り道だと思います。

最終的には、独自のカスタム ジオメトリ レイ テスト アルゴリズムの実装を移植する前に見落としていた単純な解決策があるかどうか疑問に思っています。

4

2 に答える 2

6

いくつかの考え:

  1. そのポリゴン交差プロジェクトを使用する場合は、いくつかのリークがあることに注意してください。それらのいくつか (およびその他のいくつかのランダムな観測結果) を修正するプル リクエストを発行しました。ビュー コントローラーのコードを採用することには慎重ですが (他の問題があるため)、カテゴリに伴うさまざまな制限 (特に時計回りの制限) に問題がなければ、このカテゴリは問題ないように思われます。それらが交差したかどうかのみを判断している場合の問題)。

  2. 円を一連のポリゴンに変換してからそのポリゴン交差クラスを使用するのではなく、関連するポイント間の距離を調べることができるという事実を利用して、円との交差を検出できることを利用する別のアプローチを検討するかもしれません。多角形と円の半径。問題には次の 3 つの側面があるようです。

    • 多角形のいずれかの頂点と円の中心との間の距離が円の半径よりも小さい場合、多角形と円は交差します。

      円の内側の頂点

    • 多角形は円を囲んでいますか (これは、多角形のすべての側面からの距離が円の半径よりも大きくなる特殊なケースですが、円と多角形は依然として明らかに交差しています)。CGPathこれは、を使用してポリゴンのビューが円の中心を含んでいるかどうかを確認することで簡単に実現できCGPathContainsPointます。

      ここに画像の説明を入力

    • 唯一の複雑な部分は、多角形のいずれかの辺が円と交差するかどうかを確認することです。つまり、多角形の辺と円の中心の間の最小距離が円の半径よりも小さいことを確認します。

      円の内側

    円の中心からの各辺の距離を計算するには、ポリゴンの各辺と、円の中心に面する辺 (つまり、円の中心が線分に対して垂直であることを意味し、仮想線円の中心を通る多角形の辺に垂直な線は、実際には線分と交差します)、次のことができます。

    • 多角形の頂点 (x 1 , y 1 ) と (x 2 , y 2 )の間を通る線分の方程式について、多角形のこちら側の定数ab、およびを計算します。cax + by + c = 0

    • a = (y 1 – y 2 )

    • b = (x 2 – x 1 )

    • c = (x 1 y 2 – x 2 y 1 )

    • 円の中心として(x 0 , y 0 ) を使用して、点から線までの距離を計算します。

      abs(ax0+by0+c)/sqrt(a^2+b^2)

    • その距離が円の半径よりも小さい場合、ポリゴンが円と交差していることがわかります。

この手法を使ったサンプルプロジェクトをgithubに置いています。

于 2013-09-07T02:05:11.147 に答える
1

ソリューションの内容を少し理解するために、ポイント (この場合はポリゴン ポイント) が円の内側にあるかどうかをチェックする、私が書いた便利な MKCircle 拡張機能を次に示します。楽しみ!

//MKCircle+PointInCircle.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface MKCircle (PointInCircle)

-(BOOL)coordInCircle:(CLLocationCoordinate2D)coord;

@end

//MKCircle+PointInCircle.m

#import "MKCircle+PointInCircle.h"

@implementation MKCircle (PointInCircle)

-(BOOL)coordInCircle:(CLLocationCoordinate2D)coord {

    CLLocation *locFrom = [[CLLocation alloc] initWithLatitude:self.coordinate.latitude longitude:self.coordinate.longitude];
    CLLocation *locTo = [[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude];

    double distance = [locFrom distanceFromLocation:locTo];
    BOOL isInside = (distance <= self.radius);

    return isInside;
}

@end
于 2013-09-09T17:03:12.400 に答える