【问题标题】:Java Trying to raycast in 2DJava 试图以 2D 形式进行光线投射
【发布时间】:2017-07-14 23:23:39
【问题描述】:

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

我已经尝试了 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 函数中

【问题讨论】:

    标签: java geometry 2d raycasting


    【解决方案1】:

    发现我的错误。原来我错了:

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多