我正在用java做一个小的光线投射项目,需要一些帮助。我已经为头顶光线投射算法编写了代码,所以效果很好。然而,在伪3d环境中绘制它却不是很好。
private ArrayList<Line2D.Double> calcRays(ArrayList<Wall> walls, int resolution, int maxDist) {
ArrayList<Line2D.Double> rays = new ArrayList<>();
int mx = cameraX;//this.getMouse().getMouseX();
int my = cameraY;//this.getMouse().getMouseY();
// If we exceed the right-boundary, just bail out.
if (mx > this.getGameWidth() / 2) {
return rays;
}
for (int r = 0; r < resolution; r++) {
// Compute the angle of this ray, normalized to our field of view.
double rayAngle = ThetaUtils.normalize(r, 0, resolution, angle, angle + fov);
// Compute the coordinates of the end of this ray.
int ex = (int) (mx + maxDist * Math.cos(Math.toRadians(rayAngle)));
int ey = (int) (my + maxDist * Math.sin(Math.toRadians(rayAngle)));
// Build the ray, and declare variables for finding the MINIMUM ray.
Line2D.Double ray = new Line2D.Double(mx, my, ex, ey);
Point2D.Double minRay = null;
Color minColor = null;
double minDist = Integer.MAX_VALUE;
// For each wall, find the wall that is the closest intersected
// if one exists.
for (Wall wall : walls) {
if (wall.getLine().intersectsLine(ray)) {
Point2D.Double rayEnd = wall.intersection(ray);
double dist = rayEnd.distance(mx, my);
if (dist <= minDist) {
minDist = dist;
minRay = rayEnd;
minColor = wall.getColor();
}
}
}
// If we found a nearest collision, assign it to be the end-point of the ray.
if (minRay != null) {
ray.x2 = minRay.x;
ray.y2 = minRay.y;
}
// If the ray extends beyond the separator, set that as the end-point.
ray.x2 = ThetaUtils.clamp((int) ray.x2, 0, this.getGameWidth() / 2);
rays.add(ray);
// Now... draw the rectangle in pseudo-3D.
// Fix the fish-eye effect first.
double ca = ThetaUtils.clamp((int) (this.angle + fov / 2 - rayAngle), 0, 360);
minDist = minDist * Math.cos(Math.toRadians(ca));
// X coordinate.
int rx = (int) ThetaUtils.normalize(r, 0, resolution, this.getGameWidth() / 2, this.getGameWidth());
// Wall height calculation.
final double H_OFFSET = 25.0;
final int MAX_WALL_HEIGHT = this.getGameHeight() / 2;
double wallHeight = ThetaUtils.clamp((int) (this.getGameHeight() * H_OFFSET / minDist), 0, MAX_WALL_HEIGHT);
// Y coordinate.
double lineO = this.getGameHeight() / 2.0 - wallHeight / 2.0;
ThetaGraphics.GFXContext.setColor(minColor);
ThetaGraphics.GFXContext.drawLine(rx, (int) lineO, rx, (int) (wallHeight + lineO));
}
return rays;
}
我发布的是我在投射光线和绘制3d环境方面的尝试。我将x坐标标准化为width()/2和width之间,因为我保留了一半屏幕用于自顶向下的光线视图,另一半用于此三维透视。作为参考,我的视野设置为70。
我试着到处找教程来解释代码,但没有一个能达到我所需要的程度。代码现在可以工作了,但看起来不太对劲。我觉得我的数字好像不对劲了。有人能帮忙吗?
gif格式:https://giphy.com/gifs/ojj2hgdrqlffem17yu
暂无答案!
目前还没有任何答案,快来回答吧!