受到this问题的启发,我试图自己实施光线/阴影投射。到目前为止成功轻微。我有一个问题,有时似乎光线末端没有以正确的顺序连接或根本没有用于视图多边形,这可能是由不应该击中矩形的光线引起的。有时候,所有的问题都消失了,但是小鼠的移动会让他们回来。此外,如果光线以恰好45°的方式击中它们,则光线会穿过角落。
完整的抽奖代码:
full word = Helowdi
letter that needs to be underlined : d
full word = Helow<span class="underlined">d</span>i
letter that needs to be underlined : o
full word = Hel<span class="underlined">o</span>w<span class="underlined">d</span>i
letter that needs to be underlined : e
modified word is = H<span class="underlined">e</span>l<span class="underlined">o</span>w<span class="underlined">d</span>i
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);
}
}
}
}
基本上是一个Line2D,有更多的构造函数和一些数学长度和角度计算。
This应该如何看待。 This是大多数时候的样子。所描述的两个错误都可以在图像的上半部分看到。
编辑:删除了构造函数,线段计算和手电筒计算。
编辑:修复了奇怪的连接问题,这是因为E太小了。