2d光线/阴影投射问题

dvtswwa3  于 2021-07-09  发布在  Java
关注(0)|答案(0)|浏览(249)

受这个问题的启发,我尝试自己实现光线/阴影投射。迄今为止取得了轻微的成功。我有一个问题,有时看起来光线末端没有按正确的顺序连接,或者根本没有用于视图多边形,这可能是由于光线不应该击中矩形,但却击中了矩形。有时,所有的问题都消失了,但鼠标的轻微移动会让它们恢复过来。而且,如果光线正好在45度照射到拐角处,光线就会穿过拐角° 对两边都是真实的。
全图代码:

public void paintComponent(Graphics gr) {
    super.paintComponent(gr);
    Graphics2D g = (Graphics2D) gr;

//      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    g.setColor(Color.BLACK);
    g.fillRect(0, 0, 500, 500);

    g.setColor(Color.WHITE);

    for (ArrayList<Line2D> l : rectBounds) {
        for (Line2D line : l) {
            g.drawLine((int) line.getX1(), (int) line.getY1(), (int) line.getX2(), (int) line.getY2());
        }
    }
// Commented-out code will be used in the future for a flashlight-like effect
    Point mp = this.getMousePosition();
    try {
        mx = mp.x;
        my = mp.y;
        CENTER = new Point(mx, my);
    } catch (Exception e) {
        mx = 0;
        my = 0;
    }

    ArrayList<Ray> rays = new ArrayList<Ray>();

    for (ArrayList<Line2D> l : rectBounds) {
        for (Line2D line : l) {
            Ray ray1 = calculateIntersection(rectBounds, new Ray(CENTER, (int) line.getX1(), (int) line.getY1()));
            Ray ray2 = new Ray(CENTER, (int) line.getX1(), (int) line.getY1());
            if (ray1 != null && ray1.length() <= ray2.length()) {
                rays.add(ray1);
            } else {
                rays.add(ray2);
            }
        }
    }

    ArrayList<Ray> add = new ArrayList<Ray>();

    for (Ray ray : rays) {
        add.add(calculateIntersection(rectBounds, new Ray(CENTER, ray.angle() + E, 1000)));
        add.add(calculateIntersection(rectBounds, new Ray(CENTER, ray.angle() - E, 1000)));
    }
    add.removeAll(Collections.singleton(null));

    rays.addAll(add);

    Collections.sort(rays, new Comparator<Ray>() {
        @Override
        public int compare(Ray r1, Ray r2) {
            return Double.compare(r1.angle, r2.angle);
        }
    });

    g.setColor(Color.YELLOW);
    Polygon view = new Polygon();

    for (Ray ray : rays) {
        view.addPoint((int) ray.x2, (int) ray.y2);
    }

    g.fillPolygon(view);
    g.setColor(Color.RED);

    for (Ray ray : rays) {
        g.drawLine((int) ray.getX1(), (int) ray.getY1(), (int) ray.getX2(), (int) ray.getY2());
    }

// These loops are merged when all bugs are fixed. I pulled them apart for clarification in the images, since it would draw the polygon over the rays-
    g.fillOval(247, 247, 5, 5);

}

private Ray calculateIntersection(ArrayList<ArrayList<Line2D>> rectBounds, Ray ray) {
    // Checks if the ray is intersecting with any lines in the list. Then return a new ray from the old ray's starting point to said intersection. 
ArrayList<Double> t1 = new ArrayList<Double>();

    double rpx = 0, rdx = 0, rpy = 0, rdy = 0;

    for (ArrayList<Line2D> l : rectBounds) {
        for (Line2D line : l) {
            rpx = ray.getX1();
            rpy = ray.getY1();
            rdx = ray.getX2() - ray.getX1();
            rdy = ray.getY2() - ray.getY1();

            double lpx = line.getX1();
            double lpy = line.getY1();
            double ldx = line.getX2() - line.getX1();
            double ldy = line.getY2() - line.getY1();

            double T2 = (rdx * (lpy - rpy) + rdy * (rpx - lpx)) / (ldx * rdy - ldy * rdx);
            double T1 = (lpx + ldx * T2 - rpx) / rdx;

            if (T1 > 0 && T2 > 0 && T2 < 1) {
                t1.add(T1);

            }
        }
    }
}

Ray 基本上是一个具有更多构造函数和一些长度和Angular 计算数学的line2d。
应该是这样的。大多数时候都是这样。描述的两个bug都可以在图片的上半部分看到。
编辑:删除构造函数、线段计算和手电筒计算。
编辑:修复了奇怪的连接问题,这是由于e太小。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题