Java试图在2D

时间:2017-07-14 23:23:40

标签: java geometry 2d raycasting

我有一个类Shape,它只包含绘制自身的顶点和函数, 一个Ray类,它只是一个具有更多函数的Line2D(在这种情况下是无关紧要的),以及一个将光线投射到每个形状的每个顶点的RayCaster,检查当前光线与每条线的交点,然后采取这些交叉点,选择最接近RayCaster的那个,并使用该交点创建一个新的Ray,然后绘制该光线。

我已经尝试过这样做3次而且从来没有完全正确,有些光线甚至不会出现在某些位置。我已经测试了我的代码来计算交叉点位置并且它可以工作:

public static Point2D getLineIntersection(Line2D ray, Line2D segment) {
    if(ray.intersectsLine(segment)){
        double rx1 = ray.getX1(),
                ry1 = ray.getY1(),
                rx2 = ray.getX2(),
                ry2 = ray.getY2(),
                sx1 = segment.getX1(),
                sy1 = segment.getY1(),
                sx2 = segment.getX2(),
                sy2 = segment.getY2(),
                rdx = Math.abs(rx2 - rx1),
                rdy = Math.abs(ry2 - ry1),
                sdx = Math.abs(sx2 - sx1),
                sdy = Math.abs(sy2 - sy1),
                t1, t2,
                ix, iy;

        t2 = (rdx * (sy1 - ry1) + rdy * (rx1 - sx1)) / (sdx * rdy - sdy * rdx);
        t1 = (sx1 + sdx * t2 - rx1) / rdx;

        if(t1 > 0 && 1 > t2 && t2 > 0){
            ix = rx1 + rdx * t1;
            iy = ry1 + rdy * t1;
            return new Point2D.Float((int) ix, (int) iy);
        }else
            return null;
    }else
        return null;
}

所以我把它缩小到我投射光线的地方,但我不知道错误:

public void castRays(Graphics g, ArrayList<Shape> map){
    ArrayList<Ray> rays = new ArrayList<>();
    ArrayList<Point2D> vertices = new ArrayList<>();
    ArrayList<Line2D> segments = new ArrayList<>();

    //populate vertices and segments
    for(Shape s : map){
        vertices.addAll(Arrays.asList(s.getPoints()));
        segments.addAll(s.getLines());
    }

    for(Point2D v : vertices){
        Ray ray = new Ray(x, y, (int) v.getX(), (int) v.getY());
        ArrayList<Point2D> rayIntersects = new ArrayList<>();
        Point2D closestIntersect = null;

        for(Line2D s : segments)
            if(Utils.getLineIntersection(ray.getLine(), s) != null)
                rayIntersects.add(Utils.getLineIntersection(ray.getLine(), s));

        if(rayIntersects.size() > 0){
            for(int i = 0; i < rayIntersects.size(); i++){
                if(i == 0)
                    closestIntersect = rayIntersects.get(0);
                else{
                    if(Utils.getLineLength(new Line2D.Float(x, y, (int) closestIntersect.getX(), (int) closestIntersect.getY()))
                            > Utils.getLineLength(new Line2D.Float(x, y, (int) rayIntersects.get(i).getX(), (int) rayIntersects.get(i).getY())))
                        closestIntersect = rayIntersects.get(i);
                }
            }
        }
        if(closestIntersect != null)
            rays.add(new Ray(x, y, (int) closestIntersect.getX(), (int) closestIntersect.getY()));
    }

    for(Ray r : rays)
        r.render(g, Color.WHITE);
}

public static double getLineLength(Line2D line){
    double dx = Math.abs(line.getX2() - line.getX1()),
            dy = Math.abs(line.getY2() - line.getY1());
    return Math.sqrt(dx * dx + dy * dy);
}

如果您需要更多代码,请询问,但我认为问题出在castRays函数

1 个答案:

答案 0 :(得分:2)

发现我的错误。事实证明我错了:

public static Point2D getLineIntersection(Line2D ray, Line2D segment) {
    if(ray.intersectsLine(segment)){
        double rx1 = ray.getX1(),
                ry1 = ray.getY1(),
                rx2 = ray.getX2(),
                ry2 = ray.getY2(),
                sx1 = segment.getX1(),
                sy1 = segment.getY1(),
                sx2 = segment.getX2(),
                sy2 = segment.getY2(),
                rdx = rx2 - rx1,
                rdy = ry2 - ry1,
                sdx = sx2 - sx1,
                sdy = sy2 - sy1,
                t1, t2,
                ix, iy;

        t2 = (rdx * (sy1 - ry1) + rdy * (rx1 - sx1)) / (sdx * rdy - sdy * rdx);
        t1 = (sx1 + sdx * t2 - rx1) / rdx;

        if(t1 > 0/* && 1 > t2 && t2 > 0*/){
            ix = rx1 + rdx * t1;
            iy = ry1 + rdy * t1;
            return new Point2D.Float((int) ix, (int) iy);
        }else
            return null;
    }else
        return null;
}