Raycasting with different height size
I have a java project who makes the "windows' maze" and use the ray casting algorithm. Here's a screenshot:
as you can see all the walls have the same height size. I would like to do the same but with different height size
private void castRay(int xOnScreen,double angle,double direction) {
R rx = castRayInX(angle,direction); R ry = castRayInY(angle,direction); // In case of out-of-space rays if (rx.getDistance()==Double.MAX_VALUE && ry.getDistance()==Double.MAX_VALUE) { graphics.setColor(BACKGROUND); graphics.drawLine(xOnScreen,0,xOnScreen,this.image.getHeight()); return; } double distance = rx.getDistance(); double normal = rx.getNormal(); Color c = rx.getColor(); double coef = Math.cos((angle+direction+Math.PI)-normal); Plot collision = rx.getPlot(); if (ry.getDistance()<rx.getDistance()) { distance = ry.getDistance(); normal = ry.getNormal(); c = ry.getColor(); coef = Math.cos((angle+direction+Math.PI)-normal); collision = ry.getPlot(); } coef = Math.abs(coef); int factor = map.length*SQUARE_SIZE; double d = (double)(distance+factor)/factor; coef *= 1/(d*d); Color c2 = new Color((int)(c.getRed()*coef),(int)(c.getGreen()*coef),(int)(c.getBlue()*coef)); graphics.setColor(c2);
// graphics.setColor(c); // no illumination
distance *= Math.cos(angle); // lens correction int h = (int)(this.screenDistance/distance*WALL_HEIGHT); // perspective height int vh = this.image.getHeight(); graphics.drawLine(xOnScreen,(vh-h)/2,xOnScreen,(vh+h)/2); drawEye(direction,collision);
}
private R castRayInX(double angleRay,double direction) {
double angle = angleRay+direction; double x1 = eye.getX()+SQUARE_SIZE*Math.cos(angle); double y1 = eye.getY()+SQUARE_SIZE*Math.sin(angle); double slope = (y1-eye.getY())/(x1-eye.getX()); if (Math.cos(angle)==0) { if (Math.sin(angle)>0) return new R(Double.MAX_VALUE,3*Math.PI/2,BACKGROUND,null); else return new R(Double.MAX_VALUE,Math.PI/2,BACKGROUND,null); } if (Math.cos(angle)>0) { int firstX = ((eye.getX()/SQUARE_SIZE)+1)*SQUARE_SIZE; R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null); for (int x = firstX; x<map[0].length*SQUARE_SIZE; x += SQUARE_SIZE) { int y = (int)(slope*(x-eye.getX())+eye.getY()); if (isOutside(x,y,Color.MAGENTA,this.showRayCastingX)) break; Color c = colorAt(x,y); if (c==null) c = colorAt(x,y-1); if (c==null) c = colorAt(x-1,y); if (c==null) c = colorAt(x-1,y-1); if (c!=null) { int DX = x-eye.getX(); double DY = y-eye.getY(); return new R(Math.sqrt(DX*DX+DY*DY),Math.PI,c,new Plot((int)x,(int)y, WALL_HEIGHT)); } } return r; } else { int firstX = ((eye.getX()/SQUARE_SIZE))*SQUARE_SIZE; R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null); for (int x = firstX; x>=0; x -= SQUARE_SIZE) { int y = (int)(slope*(x-eye.getX())+eye.getY()); if (isOutside(x,y,Color.MAGENTA,this.showRayCastingX)) break; Color c = colorAt(x,y); if (c==null) c = colorAt(x,y-1); if (c==null) c = colorAt(x-1,y); if (c==null) c = colorAt(x-1,y-1); if (c!=null) { int DX = x-eye.getX(); double DY = y-eye.getY(); return new R(Math.sqrt(DX*DX+DY*DY),0,c,new Plot((int)x,(int)y, WALL_HEIGHT)); } } return r; }
}
private R castRayInY(double angleRay,double direction) {
// System.out.println("cast ray 2 Y " angleRay " " direction);
double angle = angleRay+direction; double x1 = eye.getX()+SQUARE_SIZE*Math.cos(angle); double y1 = eye.getY()+SQUARE_SIZE*Math.sin(angle);
// System.out.println(eye " " x1 " " y1);
double slope = (y1-eye.getY())/(x1-eye.getX()); if (Math.sin(angle)==0) { if (Math.cos(angle)>0) return new R(Double.MAX_VALUE,Math.PI,BACKGROUND,null); else return new R(Double.MAX_VALUE,0,BACKGROUND,null); } if (Math.sin(angle)>0) { int firstY = ((eye.getY()/SQUARE_SIZE)+1)*SQUARE_SIZE; R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null); for (int y = firstY; y<map.length*SQUARE_SIZE; y += SQUARE_SIZE) { int x = (int)((y-eye.getY())/slope)+eye.getX(); if (isOutside(x,y,Color.CYAN,this.showRayCastingY)) break; Color c = colorAt(x,y); if (c==null) c = colorAt(x,y-1); if (c==null) c = colorAt(x-1,y); if (c==null) c = colorAt(x-1,y-1); if (c!=null) { double DX = x-eye.getX(); int DY = y-eye.getY(); return new R(Math.sqrt(DX*DX+DY*DY),3*Math.PI/2,c,new Plot((int)x,(int)y, WALL_HEIGHT)); } } return r; } else { int firstY = ((eye.getY()/SQUARE_SIZE))*SQUARE_SIZE; R r = new R(Double.MAX_VALUE,angle+Math.PI,BACKGROUND,null); for (int y = firstY; y>=0; y -= SQUARE_SIZE) { int x = (int)((y-eye.getY())/slope)+eye.getX(); if (isOutside(x,y,Color.CYAN,this.showRayCastingY)) break; Color c = colorAt(x,y); if (c==null) c = colorAt(x,y-1); if (c==null) c = colorAt(x-1,y); if (c==null) c = colorAt(x-1,y-1); if (c!=null) { double DX = x-eye.getX(); int DY = y-eye.getY(); return new R(Math.sqrt(DX*DX+DY*DY),Math.PI/2,c,new Plot((int)x,(int)y, WALL_HEIGHT)); } } return r; } }
My Rclass has a Plot (x, y, z) for now I use WALL_HEIGHT a color, a distance and a normal for the light. For now this works but I would like to add a new
The above is the detailed content of How can I modify the raycasting algorithm in Java to create walls of different heights in a "windows' maze"?. For more information, please follow other related articles on the PHP Chinese website!