首页  >  文章  >  Java  >  如何修改Java中的光线投射算法以在“窗户迷宫”中创建不同高度的墙壁?

如何修改Java中的光线投射算法以在“窗户迷宫”中创建不同高度的墙壁?

DDD
DDD原创
2024-11-06 16:19:02673浏览

How can I modify the raycasting algorithm in Java to create walls of different heights in a

不同高度尺寸的光线投射

我有一个java项目,它制作“windows'迷宫”并使用光线投射算法。这是一个屏幕截图:

你可以看到所有的墙壁都有相同的高度尺寸。我想做同样的事情,但高度尺寸不同

private voidcastRay(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); // 无照明

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 RcastRayInX(doubleangleRay,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 RcastRayInY(doubleangleRay) ,双向) {
// System.out.println("投射光线 2 Y " angleRay " " 方向);

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;           
    }
}

我的 Rclass 有一个图 (x, y, z) 现在我使用 WALL_HEIGHT 颜色、距离和法线光。目前这可行,但我想添加一个新的

以上是如何修改Java中的光线投射算法以在“窗户迷宫”中创建不同高度的墙壁?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn