Raycasting avec différentes tailles de hauteur
J'ai un projet Java qui crée le "labyrinthe des fenêtres" et utilise l'algorithme de lancer de rayons. Voici une capture d'écran :
comme vous pouvez le voir, tous les murs ont la même hauteur. J'aimerais faire la même chose mais avec une taille de hauteur différente
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); // pas d'éclairage
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);
}
privé 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; }
}
privé 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; } }
Mon Rclass a un Plot (x, y, z) pour l'instant j'utilise WALL_HEIGHT une couleur, une distance et une normale pour la lumière. Pour l'instant cela fonctionne mais j'aimerais ajouter un nouveau
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!