Java寻找平面上距离原点最近且超出给定半径的整数坐标点
在二维平面几何计算中,我们经常需要处理坐标点与原点距离相关的判定问题。本文要实现的需求是:给定一个半径值,在平面上寻找距离原点最近的整数坐标点,且该点到原点的距离必须严格大于给定的半径。整数坐标点指的是横纵坐标均为整数的点,比如(1,2)、(-3,0)这样的点都符合要求。
问题分析
首先我们需要明确点到原点的距离计算公式:对于点(x,y),它到原点的距离d满足 d² = x² + y²,因此判断距离是否大于半径r,等价于判断 x² + y² > r²,这样可以避免开方运算,提升计算效率。
我们需要在满足条件的点中,找到距离原点最近的点,也就是要找到满足 x² + y² > r² 的最小 x² + y² 值,对应的(x,y)就是目标点。如果存在多个点距离相同,通常返回其中任意一个即可,本文实现中默认返回第一个找到的符合条件的点。
实现思路
我们可以先预设一个最小距离平方值,初始设为比r²大的最小值,然后遍历所有可能的整数坐标点。遍历的范围可以控制在[-r-1, r+1]之间,因为如果坐标的绝对值超过r+1,那么x²或者y²就会超过(r+1)²,这类点的距离平方必然大于(r+1)²,不可能是最近的点,这样能缩小遍历范围提升效率。
遍历过程中,对每个点计算距离平方,如果大于r²且小于当前记录的最小距离平方,就更新最小距离平方和目标点坐标,最终遍历完成后得到的目标点就是所求结果。
代码实现
下面是完整的Java实现代码,包含方法定义和测试示例:
import java.util.ArrayList;
import java.util.List;
public class NearestPointFinder {
/**
* 寻找距离原点最近且距离超出给定半径的整数坐标点
* @param radius 给定的半径值,需为非负数
* @return 符合条件的点坐标列表,如果不存在则返回空列表(理论上半径有限时一定存在符合条件的点)
*/
public static List<int[]> findNearestPoint(double radius) {
List<int[]> result = new ArrayList<>();
// 半径不能为负数,做参数校验
if (radius < 0) {
return result;
}
// 计算半径的平方,避免重复开方
double radiusSquare = radius * radius;
// 遍历的边界,绝对值最大为半径+1,因为超出这个范围的点距离一定更大
int bound = (int) Math.ceil(radius) + 1;
// 记录当前找到的最小距离平方,初始设为最大值
double minDistanceSquare = Double.MAX_VALUE;
// 遍历所有可能的x坐标
for (int x = -bound; x <= bound; x++) {
// 遍历所有可能的y坐标
for (int y = -bound; y <= bound; y++) {
// 计算当前点到原点的距离平方
double currentDistanceSquare = x * x + y * y;
// 如果当前点距离大于半径,且距离平方小于当前记录的最小值
if (currentDistanceSquare > radiusSquare && currentDistanceSquare < minDistanceSquare) {
// 更新最小距离平方
minDistanceSquare = currentDistanceSquare;
// 清空之前的结果,因为找到了更近的点
result.clear();
result.add(new int[]{x, y});
} else if (currentDistanceSquare == minDistanceSquare) {
// 如果距离和当前最小值相同,加入结果列表(可选,根据需求调整)
result.add(new int[]{x, y});
}
}
}
return result;
}
public static void main(String[] args) {
// 测试示例1:半径为2.5
double radius1 = 2.5;
List<int[]> points1 = findNearestPoint(radius1);
System.out.println("半径为" + radius1 + "时的最近点:");
for (int[] point : points1) {
System.out.println("(" + point[0] + ", " + point[1] + ")");
}
// 测试示例2:半径为0,找距离大于0的最近整数点
double radius2 = 0;
List<int[]> points2 = findNearestPoint(radius2);
System.out.println("\n半径为" + radius2 + "时的最近点:");
for (int[] point : points2) {
System.out.println("(" + point[0] + ", " + point[1] + ")");
}
// 测试示例3:半径为3
double radius3 = 3;
List<int[]> points3 = findNearestPoint(radius3);
System.out.println("\n半径为" + radius3 + "时的最近点:");
for (int[] point : points3) {
System.out.println("(" + point[0] + ", " + point[1] + ")");
}
}
}代码说明
上述代码中,findNearestPoint方法是核心实现:
- 首先做了参数校验,避免传入负数的半径值。
- 通过
Math.ceil(radius) + 1计算遍历边界,确保不会遗漏可能的最近点,同时避免无意义的遍历。 - 用两层循环遍历所有x和y的可能取值,计算每个点的距离平方,和半径平方比较,同时记录最小的距离平方对应的点。
- 如果存在多个点和原点距离相同且都是最近的,代码会把所有符合条件的点都加入结果列表,方便后续按需处理。
main方法中的测试示例覆盖了不同半径的场景,比如半径为0时能找到距离原点最近的(1,0)、(-1,0)、(0,1)、(0,-1)等点,半径为2.5时能找到距离平方为9的点,比如(3,0)、(0,3)等,符合预期结果。
注意事项
需要注意的是,如果给定的半径非常大,遍历的范围bound也会相应变大,两层循环的时间复杂度是O(bound²),不过对于常规的业务场景,半径不会特别大,这个实现完全够用。如果半径极大,可以考虑优化遍历逻辑,比如先确定最小的距离平方是(r+1)²还是其他值,减少遍历次数,但常规场景下不需要做额外优化。