【发布时间】:2011-11-15 18:42:32
【问题描述】:
您好,我今天的问题是分解并弄清楚如何对算法的 LOWER TANGENT 部分进行实际编码,我已设法完成步骤 (1) 和 (2),但我现在卡在步骤 (3) 上。
分而治之的凸壳
船体(S):
(1) 如果 |S|
(2) 否则,将点集 S 划分为两个集合 A 和 B,其中 A 由 x 坐标最低的点的一半和 B 组成 由 x 坐标最高的点的一半组成。
(3) 递归计算 HA = Hull(A) 和 HB = Hull(B)。
(4) 通过计算 HA 和 HB 的上下切线并丢弃所有点 位于这两条切线之间。
http://www.cs.wustl.edu/~pless/506/l3_1.gif
寻找下切线
下切线(HA ; HB):
(1) 设 a 为 HA 的最右边点。
(2) 设 b 为 HB 的最左边点。
(3) 虽然 ab 不是 HA 和 HB 的下切线
(a) 虽然 ab 不是 HA 的下切线,但 a = a - 1(顺时针移动 a)。
(b) 虽然 ab 不是 HB 的下切线,但 b = b + 1(逆时针移动 b)。
(4) 返回 ab.
引用自:http://www.cs.wustl.edu/~pless/506/l3.html 这个解释最能描述我的问题。
没有包含 Lexisort 和 convehull 的函数,因为它们正在工作,DC hull 算法已包含在内以提供上下文。
我当前的代码:
public static int [][] dcHull(int [][]merged){
if(merged.length <= 3)
return convexHull(merged);
else {
lexiSort(merged);
//split(P, A, B);
//SPLIT
double p = merged.length;
int A;
int B;
if (p%2 == 0){//EVEN
A = (int) (p/2);
B = (int) (p/2);
}
else//ODD
A = (int) (1+(p/2));
B = (int) (p/2);
int arrayA[][] = new int[A][2];
int arrayB[][] = new int[B][2];
for (int i=0; i<A; i++){
arrayA[i][0] = merged[i][0];
arrayA[i][1] = merged[i][1];
}
for (int i=0; i<B; i++){
arrayB[i][0] = merged[i+A][0];
arrayB[i][1] = merged[i+A][1];
}
for ( int i=0; i<arrayA.length; i++){
System.out.println( "Merged array A Coordinates: " + arrayA[i][0] +", " + arrayA[i][1]);}
for ( int i=0; i<arrayB.length; i++){
System.out.println( "Merged array B Coordinates: " + arrayB[i][0] +", " + arrayB[i][1]);}
lowerT(arrayA, arrayB);
//upperT(arrayA, arrayB);
return merged(dcHull(convexHull(arrayA)), dcHull(convexHull(arrayB)));
}
}
public static int[][] lowerT(int [][] hulla, int [][] hullb){
int a = 0;
int b = 0;
//LOWER TANGENT
//(1) Let a be the rightmost point of HA .
for (int i=0; i<hulla.length; i++){
if (a < hulla[i][0]){
a = hulla[i][0];
}
}
//(2) Let b be the leftmost point of HB .
for (int i=0; i<hullb.length; i++){
if (b < hullb[i][0]){
b = hullb[i][0];
}
}
for (int i=0; i<hullb.length; i++){
if (b > hullb[i][0]){
b = hullb[i][0];
}
}
代码在计算出 HA 的 a 和 HB 的 b 后完成,但是我不明白 (3) 或更确切地说如何使用我拥有的元素对其进行编码。
(1) 设 a 为 HA 的最右边点。
(2) 设 b 为 HB 的最左边点。
我认为还有一种称为右转的附加代码方法很有用: “下切线是一个条件,可以 通过两个顶点的方向测试进行局部测试,并且 船体上的相邻顶点。”
我只是不知道如何组合起来。
public static boolean rightTurn(int [][] rt, int counter) //AxBxC = (Bx-Ax)(Cy-Ay)-(By-Ay)(Cx-Ax)
{
int ax = rt[counter-2][0];
int bx = rt[counter-1][0];
int cx = rt[counter][0];
int ay = rt[counter-2][1];
int by = rt[counter-1][1];
int cy = rt[counter-0][1];
int result =(bx-ax)*(cy-ay)-(by-ay)*(cx-ax);
if (result < 0){ // Result = VE+ (Right Turn), 0, VE- (Left Turn)
return true; //VE- = TRUE = Right Turn
}
else return false; //VE+ = FALSE = Left Turn
}
【问题讨论】:
-
这是很多人必须阅读和理解的工作。你有没有机会把它配对一下,以便更容易提供一些帮助?
-
对不起,我没有早点回复你,我还没习惯这个系统。当然,我将来会更明确地格式化我的问题。 =)
标签: java