Java线段相交计算传入全零坐标触发NullPointerException如何解决
问题根因
你遇到的两个异常触发逻辑非常明确:
- 构造方法抛出
IllegalArgumentException:你当前的构造逻辑已经明确校验了起止点不能相同,测试代码传入两个(0,0)创建Segment对象时,会直接在校验步骤触发该异常,代码不会执行到后续求交逻辑。 NullPointerException:一是intersection方法判断线段平行/共线时会直接返回null,你后续直接调用返回值的getX()/getY()方法就会触发空指针;二是你当前贴出的intersection代码中div、dy2、dx1等核心变量未定义,运行时也会触发异常。
修复方案
1 代码逻辑层面优化
完善线段求交方法
你当前的intersection只做了平行判断,缺少直线交点计算、交点是否落在线段范围内的校验逻辑,完整实现参考如下:
import java.awt.Point; public class Segment { private final Point start; private final Point end; public Segment(Point start, Point end) { if (start == null || end == null) throw new IllegalArgumentException("Arguments can't be null"); if (start.equals(end)) throw new IllegalArgumentException("The points must differ"); this.start = start; this.end = end; } public Point intersection(Segment another) { // 计算两条线段的方向向量 double dx1 = this.end.x - this.start.x; double dy1 = this.end.y - this.start.y; double dx2 = another.end.x - another.start.x; double dy2 = another.end.y - another.start.y; double div = dy2 * dx1 - dx2 * dy1; // 平行/共线无交点 if (Math.abs(div) < 1.0e-10) return null; // 计算交点的参数值 double t = ((another.start.x - this.start.x) * dy2 - (another.start.y - this.start.y) * dx2) / div; double u = ((another.start.x - this.start.x) * dy1 - (another.start.y - this.start.y) * dx1) / div; // 交点必须同时落在两条线段范围内(t和u都在0到1之间) if (t >= 0 && t <= 1 && u >= 0 && u <= 1) { int x = (int) (this.start.x + t * dx1); int y = (int) (this.start.y + t * dy1); return new Point(x, y); } // 直线交点不在线段上 return null; } public Point getStart() { return start; } public Point getEnd() { return end; } }
修正测试逻辑
测试时要符合构造方法的参数约束,同时对求交结果做非空判断:
public class Test { public static void main(String[] args) { try { // 构造符合要求的线段,不能传入相同起止点 Segment first = new Segment(new Point(0, 0), new Point(2, 2)); Segment second = new Segment(new Point(0, 2), new Point(2, 0)); Point intersection = first.intersection(second); // 先判空再操作返回值 if (intersection != null) { System.out.println(intersection.getX()); System.out.println(intersection.getY()); } else { System.out.println("两条线段无交点"); } } catch (IllegalArgumentException e) { // 捕获构造方法抛出的参数异常 System.out.println("线段参数非法:" + e.getMessage()); } } }
2 异常处理适配
如果你的业务场景允许传入相同的起止点,可以修改构造方法的校验逻辑:
- 移除抛异常的代码,将长度为0的线段当做特殊情况处理,在
intersection方法中单独判断该点是否落在另一条线段上 - 如果不允许传入相同点,就提前在调用构造方法前做参数校验,避免触发运行时异常
内容的提问来源于stack exchange,提问作者user13921628
相关产品推荐
相关产品推荐

