おそらく、これはプログラミングの質問というよりも数学の質問ですが、XNA で回転キャリパー アルゴリズムを実装しようとしています。
ウィキペディアで詳述されているように、モノトーンチェーンを使用して、ポイントセットから凸包を推測しました。
ここで見つかった OBB の後に OBB を見つけるアルゴリズムをモデル化しようとしています: http://www.cs.purdue.edu/research/technical_reports/1983/TR%2083-463.pdf
ただし、最終ページで言及されている DOTPR および CROSSPR メソッドが何を返すことになっているのかわかりません。
2 点の内積と 2 点の外積を取得する方法は理解していますが、これらの関数は 2 つのエッジ/線分の内積と外積を返すことになっているようです。私の数学の知識は確かに限られていますが、これはアルゴリズムが何を探しているかについての私の最善の推測です
public static float PolygonCross(List<Vector2> polygon, int indexA, int indexB)
{
var segmentA1 = NextVertice(indexA, polygon) - polygon[indexA];
var segmentB1 = NextVertice(indexB, polygon) - polygon[indexB];
float crossProduct1 = CrossProduct(segmentA1, segmentB1);
return crossProduct1;
}
public static float CrossProduct(Vector2 v1, Vector2 v2)
{
return (v1.X * v2.Y - v1.Y * v2.X);
}
public static float PolygonDot(List<Vector2> polygon, int indexA, int indexB)
{
var segmentA1 = NextVertice(indexA, polygon) - polygon[indexA];
var segmentB1 = NextVertice(indexB, polygon) - polygon[indexB];
float dotProduct = Vector2.Dot(segmentA1, segmentB1);
return dotProduct;
}
ただし、コードのこの部分で指示されているようにこれらのメソッドを使用すると...
while (PolygonDot(polygon, i, j) > 0)
{
j = NextIndex(j, polygon);
}
if (i == 0)
{
k = j;
}
while (PolygonCross(polygon, i, k) > 0)
{
k = NextIndex(k, polygon);
}
if (i == 0)
{
m = k;
}
while (PolygonDot(polygon, i, m) < 0)
{
m = NextIndex(m, polygon);
}
..ポイントのテスト セットを指定すると、j、k に対して同じインデックスが返されます。
List<Vector2> polygon = new List<Vector2>()
{
new Vector2(0, 138),
new Vector2(1, 138),
new Vector2(150, 110),
new Vector2(199, 68),
new Vector2(204, 63),
new Vector2(131, 0),
new Vector2(129, 0),
new Vector2(115, 14),
new Vector2(0, 138),
};
perdue.edu の技術文書に示されているように、これらのポイントを反時計回りの順序で配置するために polygon.Reverse を呼び出すことに注意してください。ポイントセットの凸包を見つけるための私のアルゴリズムは、反時計回りの順序でポイントのリストを生成しますが、y < 0 が y > 0 よりも高いと仮定します。 . リストを逆にするだけで十分なようです。最後に重複したポイントも削除します。
このプロセスの後、データは次のようになります。
- ベクトル 2(115, 14)
- ベクトル 2(129, 0)
- ベクトル 2(131, 0)
- ベクトル 2(204, 63)
- ベクトル 2(199, 68)
- ベクトル2(150, 110)
- ベクトル 2(1, 138)
- ベクトル2(0, 138)
i が 0 で j が 3 の場合、このテストは最初のループで失敗します。 (115,14) から (204,63) への線分と (204,63) から (199,68) への線分の外積は次のようになります。 ) は 0 です。次に、同じ行の内積も 0 であることがわかります。したがって、j と k は同じインデックスを共有します。
対照的に、このテスト セットが与えられた場合: http://www.wolframalpha.com/input/?i=polygon+%282%2C1%29%2C%281%2C2%29%2C%281%2C3%29%2C% 282%2C4%29%2C%284%2C4%29%2C%285%2C3%29%2C%283%2C1%29
私のコードは、この OBB を正常に返します 。 2C%285%2C3%29
http://www.geometrictools.com/LibMathematics/Containment/Wm5ContMinBox2.cppにある C++ アルゴリズムを読んだことがありますが、あまりにも複雑すぎて完全に従うことができません。また、上記の論文で詳述されている他のものとは大きく異なるようです。
2 つの線分の内積と外積を見つけるために、スキップしているステップを知っている人や、コードにエラーが表示されている人はいますか? 以前にこのコードを C# で正常に実装し、例を持っている人はいますか?