Java中三点外心计算的斜率为0边缘情况处理问询
解决三点外心计算中斜率为0的边缘问题
我明白你遇到的问题了——当三点中有两点在水平线上(斜率为0)时,原来的外心计算代码会出问题,这通常是因为我们在计算垂直平分线时,直接用了斜率的倒数(也就是垂直斜率),但斜率为0的话,垂直斜率是无穷大,没法用常规的点斜式表示,自然会报错或者计算错误。
问题根源
当两点的y坐标相等(比如A(x₁,y)和B(x₂,y)),它们的连线是水平线,斜率为0,对应的垂直平分线是竖直线,方程是 x = (x₁ + x₂) / 2,这时候如果还按常规方法计算斜率(比如用-1/slope),就会出现除以0的情况,直接导致程序崩溃或者结果异常。
修改方案
我们需要在计算垂直平分线前,先判断两种特殊情况:
- 两点水平(y坐标相等):直接用
x = (x₁+x₂)/2作为垂直平分线方程 - 两点垂直(x坐标相等):直接用
y = (y₁+y₂)/2作为垂直平分线方程 - 普通情况:再用斜率计算垂直平分线的点斜式,然后联立两个垂直平分线方程求交点(外心)
修改后的完整代码
import java.util.Scanner; class CircleTest { public static void main(String args[]) { int[] x = new int[3]; int[] y = new int[3]; Scanner sc = new Scanner(System.in); System.out.println("请输入3个点的坐标(每行输入x和y):"); for (int i = 0; i < 3; i++) { System.out.print("点" + (i+1) + "的x坐标:"); x[i] = sc.nextInt(); System.out.print("点" + (i+1) + "的y坐标:"); y[i] = sc.nextInt(); } // 计算外心(x0, y0) double x0, y0; // 取前两个点,判断是否水平/垂直 boolean isHorizontal1 = (y[0] == y[1]); boolean isVertical1 = (x[0] == x[1]); // 取后两个点,判断是否水平/垂直 boolean isHorizontal2 = (y[1] == y[2]); boolean isVertical2 = (x[1] == x[2]); if (isHorizontal1) { // 第一个垂直平分线是竖直线x=(x0+x1)/2 x0 = (x[0] + x[1]) / 2.0; // 用第二个垂直平分线求y0 if (isVertical2) { y0 = (y[1] + y[2]) / 2.0; } else { double slope2 = (double)(y[2] - y[1]) / (x[2] - x[1]); double perpSlope2 = -1.0 / slope2; double midX2 = (x[1] + x[2]) / 2.0; double midY2 = (y[1] + y[2]) / 2.0; // 代入x0求y0 y0 = perpSlope2 * (x0 - midX2) + midY2; } } else if (isVertical1) { // 第一个垂直平分线是水平线y=(y0+y1)/2 y0 = (y[0] + y[1]) / 2.0; // 用第二个垂直平分线求x0 if (isHorizontal2) { x0 = (x[1] + x[2]) / 2.0; } else { double slope2 = (double)(y[2] - y[1]) / (x[2] - x[1]); double perpSlope2 = -1.0 / slope2; double midX2 = (x[1] + x[2]) / 2.0; double midY2 = (y[1] + y[2]) / 2.0; // 代入y0求x0 x0 = (y0 - midY2) / perpSlope2 + midX2; } } else { // 普通情况,联立两条垂直平分线方程求解 double slope1 = (double)(y[1] - y[0]) / (x[1] - x[0]); double perpSlope1 = -1.0 / slope1; double midX1 = (x[0] + x[1]) / 2.0; double midY1 = (y[0] + y[1]) / 2.0; double slope2 = (double)(y[2] - y[1]) / (x[2] - x[1]); double perpSlope2 = -1.0 / slope2; double midX2 = (x[1] + x[2]) / 2.0; double midY2 = (y[1] + y[2]) / 2.0; // 联立点斜式方程求交点 x0 = (perpSlope2*midX2 - perpSlope1*midX1 + midY1 - midY2) / (perpSlope2 - perpSlope1); y0 = perpSlope1*(x0 - midX1) + midY1; } System.out.printf("外心坐标为:(%.2f, %.2f)%n", x0, y0); sc.close(); } }
代码说明
- 特殊情况判断:先检查每对点是否水平或垂直,直接生成对应的垂直平分线方程,彻底避免除以0的错误
- 精度处理:所有计算都用
double类型,避免整数除法导致的精度丢失问题 - 高效求解:普通情况直接用代数方法联立两条垂直平分线的点斜式,一步算出交点,不用额外的循环或迭代
这样修改后,无论是斜率为0的水平点,还是斜率无穷大的垂直点,都能正确计算外心啦。
内容的提问来源于stack exchange,提问作者quadgen
相关产品推荐
相关产品推荐

