You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 04:00:00