gpt4 book ai didi

java - 格雷厄姆扫描的问题

转载 作者:行者123 更新时间:2023-12-02 04:48:41 26 4
gpt4 key购买 nike

目前正在将 Graham's Scan 与 Convex HUll 结合使用。我是一名学生,所以我想自己完成它,但是我一直在筛选多个网站来寻找答案。简而言之,我有我的构造函数,一个来自文件,一个随机生成,正在工作,因此我能够创建一系列点。下一步是实现快速排序,按极角排序。这是通过比较器类完成的。比较器类是我陷入困境的地方,我们被告知使用点比较和交叉比较来进行角度比较,但我很迷失。

/**
* Use cross product and dot product to implement this method. Do not take square roots
* or use trigonometric functions. See the PowerPoint notes on how to carry out cross and
* dot products.
*
* Call comparePolarAngle() and compareDistance().
*
* @param p1
* @param p2
* @return -1 if one of the following three conditions holds:
* a) p1 and referencePoint are the same point but p2 is a different point;
* b) neither p1 nor p2 equals referencePoint, and the polar angle of
* p1 with respect to referencePoint is less than that of p2;
* c) neither p1 nor p2 equals referencePoint, p1 and p2 have the same polar
* angle w.r.t. referencePoint, and p1 is closer to referencePoint than p2.
* 0 if p1 and p2 are the same point
* 1 if one of the following three conditions holds:
* a) p2 and referencePoint are the same point but p1 is a different point;
* b) neither p1 nor p2 equals referencePoint, and the polar angle of
* p1 with respect to referencePoint is greater than that of p2;
* c) neither p1 nor p2 equals referencePoint, p1 and p2 have the same polar
* angle w.r.t. referencePoint, and p1 is further to referencePoint than p2.
*
*/
public int compare(Point p1, Point p2){
if(p1 == referencePoint && p2 != referencePoint){
return -1;
} else if(p1 == p2){
return 0;
} else {

}
return 0;
}


/**
* Compare the polar angles of two points p1 and p2 with respect to referencePoint. Use
* cross products. Do not use trigonometric functions.
*
* Precondition: p1 and p2 are distinct points.
*
* @param p1
* @param p2
* @return -1 if p1 equals referencePoint or its polar angle with respect to referencePoint
* is less than that of p2.
* 0 if p1 and p2 have the same polar angle.
* 1 if p2 equals referencePoint or its polar angle with respect to referencePoint
* is less than that of p1.
*/
public int comparePolarAngle(Point p1, Point p2){
// TODO
return 0;
}


/**
* Compare the distances of two points p1 and p2 to referencePoint. Use dot products.
* Do not take square roots.
*
* @param p1
* @param p2
* @return -1 if p1 is closer to referencePoint
* 0 if p1 and p2 are equidistant to referencePoint
* 1 if p2 is closer to referencePoint
*/
public int compareDistance(Point p1, Point p2){
int distance = 0;

return distance;
}

这就是全部,我只是在陷入困境之前在比较方法上经历了一些小事情。

快速排序和分区方法非常标准,但我将添加它们,以便你们可以广泛了解所有内容:

/**
* Sort the array points[] in the increasing order of polar angle with respect to lowestPoint.
* Use quickSort. Construct an object of the pointComparator class with lowestPoint as the
* argument for point comparison.
*
* Ought to be private, but is made public for testing convenience.
*/
public void quickSort(){

// TODO
}


/**
* Operates on the subarray of points[] with indices between first and last.
*
* @param first starting index of the subarray
* @param last ending index of the subarray
*/
private void quickSortRec(int first, int last){

// TODO
}


/**
* Operates on the subarray of points[] with indices between first and last.
*
* @param first
* @param last
* @return
*/
private int partition(int first, int last){

// TODO
return 0;
}

我知道我本质上需要先启动并运行 Compare 类,然后才能开始快速排序方法,但我觉得我根本不知道如何使用点/交叉比较,所以我感觉真的迷失了.

如果有人愿意帮忙,我将不胜感激!非常感谢您的浏览,祝您度过一个美好的夜晚。

最佳答案

在所有这些方法中,当您需要查看两个 Point 对象是否相等时,您应该使用 Point 的 equals 方法,而不是“==”:

if(p1.equals(p2)) {
//code
}

实现比较

请注意,您的比较方法需要在其实现中使用 equals()、comparePolarAngle() 和 CompareDistance()。最后一组条件(返回 1)也可以在 else 语句中处理。

public int compare(Point p1, Point p2) {
if(p1.equals(p2)) {
return 0;
}
else if(p1.equals(referencePoint) ||
(!p1.equals(referencePoint) && !p2.equals(referencePoint) && comparePolarAngle(p1, p2) == -1) ||
(!p1.equals(referencePoint) && !p2.equals(referencePoint) && comparePolarAngle(p1, p2) == 0 && compareDistance(p1, p2) == -1))
{
return -1;
}
else {
return 1;
}
}

实现比较距离

这里我们需要的主要信息是如何仅使用点积来确定从referencePoint到Point对象的 vector 的长度。首先,让我们实现一个辅助方法,该方法将两个点作为输入并以整数值形式返回点积。

private int dotProduct(Point p1, Point p2) {
int p1X = p1.getX() - referencePoint.getX();
int p1Y = p1.getY() - referencePoint.getY();
int p2X = p2.getX() - referencePoint.getX();
int p2Y = p2.getY() - referencePoint.getY();
//compensate for a reference point other than (0, 0)

return (p1X * p2X) + (p1Y * p2Y); //formula for dot product
}

那么我们如何使用它来计算 vector 的长度呢?如果我们将一个点与其自身进行点积,我们会得到 (xx) + (yy),这是毕达哥拉斯定理 (a^2 + b^2 = c^) 的左侧2)。因此,如果我们调用 dotProduct(p1, p1),我们将得到其 vector 长度的平方。现在让我们实现compareDistance。

public int compareDistance(Point p1, Point p2) {
if(dotProduct(p1, p1) == dotProduct(p2, p2)) {
return 0;
}
else if(dotProduct(p1, p1) < dotProduct(p2, p2)) {
return -1;
}
else {
return 1;
}
}

不需要对点积求平方根,只需比较长度的平方即可。另请注意,此处可以使用“==”,因为我们比较的是整数,而不是点。

实现comparePolarAngle

与点积一样,让我们​​实现一个计算两个输入点的叉积的辅助方法。

private int crossProduct(Point p1, Point p2) {
int p1X = p1.getX() - referencePoint.getX();
int p1Y = p1.getY() - referencePoint.getY();
int p2X = p2.getX() - referencePoint.getX();
int p2Y = p2.getY() - referencePoint.getY();
//compensate for a reference point other than (0, 0)

return (p1X * p2Y) - (p2X * p1Y); //formula for cross product
}

另一种写出两点叉积结果的方法是 |p1||p2|sin(theta),其中 |p1|是 p1 vector 的长度,|p2|是 p2 vector 的长度,theta 是 p1 到 p2 的角度。

相对于引用点具有相同极角的两个点的 theta 值为零。 sin(0) = 0,所以极角相同的两点的叉积为零。

如果p1相对于引用点的极角小于p2的极角,则p1到p2的角度为正。对于 0 < theta < 180,sin(theta) 为正。因此,如果p1和p2的叉积为正,则p1的极角一定小于p2的极角。

如果p1相对于引用点的极角大于p2的极角,则p1到p2的角度将为负。对于 -180 < theta < 0,sin(theta) 为负数。因此,如果p1和p2的叉积为负,则p1的极角一定大于p2的极角。

利用这些信息,我们最终可以实现comparePolarAngle。

public int comparePolarAngle(Point p1, Point p2) {
if(crossProduct(p1, p2) == 0) {
return 0;
}
else if(p1.equals(referencePoint) || crossProduct(p1, p2) > 0) {
return -1;
}
else {
return 1;
}
}

我将把快速排序的实现留给你,因为我不知道你的 Point 对象是如何存储、访问和比较的。

关于java - 格雷厄姆扫描的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29453278/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com