受这个问题的启发,我尝试自己实现光线/阴影投射。迄今为止取得了轻微的成功。我有一个问题,有时看起来光线末端没有按正确的顺序连接,或者根本没有用于视图多边形,这可能是由于光线不应该击中矩形,但却击中了矩形。有时,所有的问题都消失了,但鼠标的轻微移动会让它们恢复过来。而且,如果光线正好在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太小。
暂无答案!
目前还没有任何答案,快来回答吧!