6

この記事のアルゴリズム1に従って、点が三角形の内側にあるかどうかを確認します。これは私のコードです:

//========================================================================================================================//
// Methods
//========================================================================================================================//

private float getPerpDotProduct(final PointF p1, final PointF p2) {
    return p1.x * p2.y - p1.y * p2.x;
}

private boolean isInside(final PointF pPoint) { 
    final float c1 = this.getPerpDotProduct(this.mA, pPoint);
    final float c2 = this.getPerpDotProduct(this.mB, pPoint);
    final float c3 = this.getPerpDotProduct(this.mC, pPoint);

    return ((c1 >= 0 && c2 >= 0 & c3 >= 0) || (c1 <= 0 && c2 <= 0 && c3 <= 0));
}

そしてこれが私のテストです: ここに画像の説明を入力してください

シアンゾーン:私が与える本当の三角形。

ピンクゾーン:三角形の「内側」

ブルーゾーン:三角形の「外側」

編集:

これは、ベクトルで計算するための私の新しいコードです。

private PointF getVector(final PointF pPoint1, final PointF pPoint2) {
    return new PointF(pPoint2.x - pPoint1.x, pPoint2.y - pPoint1.y);
}

private float getPerpDotProduct(final PointF p1, final PointF p2) {
    return p1.x * p2.y - p1.y * p2.x;
}

private boolean isInside(final PointF pPoint) { 
    final float c1 = this.getPerpDotProduct(getVector(this.mA, this.mB), getVector(this.mA, pPoint));
    final float c2 = this.getPerpDotProduct(getVector(this.mB, this.mC), getVector(this.mB, pPoint));
    final float c3 = this.getPerpDotProduct(getVector(this.mC, this.mA), getVector(this.mC, pPoint));

    return ((c1 > 0 && c2 > 0 & c3 > 0) || (c1 < 0 && c2 < 0 && c3 < 0));
}

私のコードを明確にしてください。ありがとうございました。

4

2 に答える 2

1

何をする必要があるかについての記事の説明には「バグ」があります。

テストポイントPを使用して、3つのポイントV1、V2、V3すべてのperpDotProduct/外積を計算します。

「テストポイントPへのベクトルを使用して3つのベクトルすべてのperpDotProduct/外積を計算する」である必要があります。

true記事で説明されているように、3つのポイントすべてが原点(画像の左上隅)から同じ「角度方向」に表示されている場合、アルゴリズムは戻ります。あなたの写真もそれを正確に示しています。(0, p)すべてのピンクの点のベクトルは、それらが青いゾーンの上にある場合、三角形に到達するために時計回りに回転する必要があります。それらがブルーゾーンの下にある場合、ベクトルは反時計回りに移動する必要があります。

{(V1-V2), (V1-P)}アルゴリズムを修正するには、ベクトル、、、{(V2-V3), (V2-P)}およびの外積を計算する必要があります{(V3-V1), (V3-P)}。擬似コードについては、この記事を参照してください。

于 2012-07-08T11:19:08.540 に答える
1

私は通常、重心座標を使用してこのような計算を行います:( p1、p2、p3が三角形で、p4がチェックしたい点である4つの点を考慮します:(p1、p3)をベクトルp1->p3と見なします

dot00 = (p1,p3).(p1,p3)
dot01 = (p1,p3).(p1,p2)
dot02 = (p1,p3).(p1,p4)
dot11 = (p1,p2).(p1,p2)
dot12 = (p1,p2).(p1,p4)


inverseDenominator = (1 / (dot00*dot11 - dot01*dot01)

u = (dot11 * dot02 - dot01*dot12) * inverseDenominator
v = (dot00 * dot12 - dot01*dot02) * inverseDenominator

重心座標が計算されたので、検証は簡単です。P4が三角形(P1、P2、P3)$の内側にあり、u正でvあり、合計すると、1より小さくなければなりません。

u >= 0 && v >= 0 && u + v < 1 

これは、私が自分の論文を書いているときにそれを行う方法を学んだ記事です:http ://www.blackpawn.com/texts/pointinpoly/default.html (変数名との類似点が見つかります:p)

于 2012-07-08T11:37:44.160 に答える