Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我应该如何在3D引擎中实现视图剪裁平面?_Java_3d_Intersection_Parametric Equations - Fatal编程技术网

Java 我应该如何在3D引擎中实现视图剪裁平面?

Java 我应该如何在3D引擎中实现视图剪裁平面?,java,3d,intersection,parametric-equations,Java,3d,Intersection,Parametric Equations,这个项目完全是用Java从头开始编写的。自从新冠病毒出现以来,我一直很无聊,所以我想要一些能占用我时间的东西,教我一些酷的东西。不过,我已经在这个问题上纠缠了大约一个星期了。当我尝试使用近平面剪裁方法时,它会将新顶点倾斜到屏幕的另一侧,但有时效果很好 所以我的想法可能是,因为它有时有效,我只是没有在管道中的正确时间进行剪辑 我从面部剔除和照明开始 然后我对顶点应用摄影机视图变换 然后我在近平面上剪辑 最后,我应用投影矩阵并剪辑任何剩余的屏幕外三角形 代码: 这将计算交点。抱歉,如果太麻烦或太

这个项目完全是用Java从头开始编写的。自从新冠病毒出现以来,我一直很无聊,所以我想要一些能占用我时间的东西,教我一些酷的东西。不过,我已经在这个问题上纠缠了大约一个星期了。当我尝试使用近平面剪裁方法时,它会将新顶点倾斜到屏幕的另一侧,但有时效果很好

所以我的想法可能是,因为它有时有效,我只是没有在管道中的正确时间进行剪辑

我从面部剔除和照明开始

然后我对顶点应用摄影机视图变换

然后我在近平面上剪辑

最后,我应用投影矩阵并剪辑任何剩余的屏幕外三角形

代码:

这将计算交点。抱歉,如果太麻烦或太长,我对编码不是很有经验,我的专业是物理,不是计算机科学

public Vertex vectorIntersectPlane(Vector3d planePos, Vector3d planeNorm, Vector3d lineStart, Vector3d lineEnd){

    float planeDot = planeNorm.dotProduct(planePos);
    float startDot = lineStart.dotProduct(planeNorm);
    float endDot = lineEnd.dotProduct(planeNorm);
    float midPoint = (planeDot - startDot) / (endDot - startDot);

    Vector3d lineStartEnd = lineEnd.sub(lineStart);
    Vector3d lineToIntersect = lineStartEnd.scale(midPoint);

    return new Vertex(lineStart.add(lineToIntersect));
}

public float distanceFromPlane(Vector3d planePos, Vector3d planeNorm, Vector3d vert){

    float x = planeNorm.getX() * vert.getX();
    float y = planeNorm.getY() * vert.getY();
    float z = planeNorm.getZ() * vert.getZ();

    return (x + y + z - (planeNorm.dotProduct(planePos)));
}

//When a triangle gets clipped it has 4 possible outcomes
// 1 it doesn't actually need clipping and gets returned
// 2 it gets clipped into 1 new triangle, for testing these are red
// 3 it gets clipped into 2 new triangles, for testing 1 is green, and 1 is blue
// 4 it is outside the view planes and shouldn't be rendered
public void clipTriangles(){

    Vector3d planePos = new Vector3d(0, 0, ProjectionMatrix.fNear, 1f);
    Vector3d planeNorm = Z_AXIS.clone();

    final int length = triangles.size();

    for(int i = 0; i < length; i++) {

        Triangle t = triangles.get(i);

        if(!t.isDraw())
            continue;

        Vector3d[] insidePoint = new Vector3d[3];
        int insidePointCount = 0;

        Vector3d[] outsidePoint = new Vector3d[3];
        int outsidePointCount = 0;

        float d0 = distanceFromPlane(planePos, planeNorm, t.getVerticesVectors()[0]);
        float d1 = distanceFromPlane(planePos, planeNorm, t.getVerticesVectors()[1]);
        float d2 = distanceFromPlane(planePos, planeNorm, t.getVerticesVectors()[2]);

        //Storing distances from plane and counting inside outside points
        {
            if (d0 >= 0){

                insidePoint[insidePointCount] = t.getVerticesVectors()[0];
                insidePointCount++;
            }else{

                outsidePoint[outsidePointCount] = t.getVerticesVectors()[0];
                outsidePointCount++;
            }
            if (d1 >= 0){

                insidePoint[insidePointCount] = t.getVerticesVectors()[1];
                insidePointCount++;
            }else{

                outsidePoint[outsidePointCount] = t.getVerticesVectors()[1];
                outsidePointCount++;
            }
            if (d2 >= 0){

                insidePoint[insidePointCount] = t.getVerticesVectors()[2];
                insidePointCount++;
            }else{

                outsidePoint[outsidePointCount] = t.getVerticesVectors()[2];
            }
        }
     
        //Triangle has 1 point still inside view, remove original triangle add new clipped triangle
        if (insidePointCount == 1) {

            t.dontDraw();

            Vertex newVert1 = vectorIntersectPlane(planePos, planeNorm, insidePoint[0], outsidePoint[0]);
            Vertex newVert2 = vectorIntersectPlane(planePos, planeNorm, insidePoint[0], outsidePoint[1]);
            vertices.add(newVert1);
            vertices.add(newVert2);
            
            //Triangles are stored with vertex references instead of the actual vertex object. 
            Triangle temp = new Triangle(t.getVertKeys()[0], vertices.size() - 2, vertices.size() - 1, vertices);
            temp.setColor(1,0,0, t.getBrightness(), t.getAlpha());
            triangles.add(temp);

            continue;
        }


        //Triangle has two points inside remove original add two new clipped triangles
        if (insidePointCount == 2) {

            t.dontDraw();

            Vertex newVert1 = vectorIntersectPlane(planePos, planeNorm, insidePoint[0], outsidePoint[0]);
            Vertex newVert2 = vectorIntersectPlane(planePos, planeNorm, insidePoint[1], outsidePoint[0]);
            vertices.add(newVert1);
            vertices.add(newVert2);

            Triangle temp = new Triangle(t.getVertKeys()[0], t.getVertKeys()[1], vertices.size() - 1, vertices);
            temp.setColor(0, 1, 0, t.getBrightness(), t.getAlpha());
            triangles.add(temp);

            temp = new Triangle(t.getVertKeys()[0], t.getVertKeys()[1], vertices.size() - 2, vertices);
            temp.setColor(0, 0, 1, t.getBrightness(), t.getAlpha());
            triangles.add(temp);

            continue;
        }
    }
}
公共顶点向量相交平面(向量3D planePos、向量3D planeNorm、向量3D lineStart、向量3D lineEnd){
float planeDot=planeNorm.dotProduct(planePos);
float startDot=lineStart.dotProduct(planeNorm);
float endDot=lineEnd.dotProduct(planeNorm);
浮点中点=(平面点-开始点)/(结束点-开始点);
Vector3d lineStartEnd=lineEnd.sub(lineStart);
Vector3d lineToIntersect=lineStartEnd.scale(中点);
返回新顶点(lineStart.add(lineToIntersect));
}
公共浮动距离平面(矢量3D平面位置、矢量3D平面标准、矢量3D垂直){
float x=planeNorm.getX()*vert.getX();
float y=planeNorm.getY()*vert.getY();
float z=planeNorm.getZ()*vert.getZ();
返回(x+y+z-(planeNorm.dotProduct(planePos));
}
//当一个三角形被剪裁时,它有4种可能的结果
//1它实际上不需要剪裁,可以返回
//2它被剪成1个新三角形,用于测试这些三角形是否为红色
//3它被剪成两个新三角形,用于测试1是绿色,1是蓝色
//4它位于视图平面之外,不应渲染
公共void clipTriangles(){
Vector3d planePos=新的Vector3d(0,0,ProjectionMatrix.fNear,1f);
Vector3d planeNorm=Z_轴。克隆();
最终整数长度=三角形。大小();
for(int i=0;i=0){
insidePoint[insidePointCount]=t.getVerticesVectors()[0];
insidePointCount++;
}否则{
outsidePoint[outsidePointCount]=t.getVerticesVectors()[0];
outsidePointCount++;
}
如果(d1>=0){
insidePoint[insidePointCount]=t.getVerticesVectors()[1];
insidePointCount++;
}否则{
outsidePoint[outsidePointCount]=t.getVerticesVectors()[1];
outsidePointCount++;
}
如果(d2>=0){
insidePoint[insidePointCount]=t.getVerticesVectors()[2];
insidePointCount++;
}否则{
outsidePoint[outsidePointCount]=t.getVerticesVectors()[2];
}
}
//三角形有1个点仍在视图内,删除原始三角形添加新的剪裁三角形
如果(insidePointCount==1){
t、 dontDraw();
顶点newVert1=向量相交平面(planePos,planeNorm,内点[0],外点[0]);
顶点newVert2=向量相交平面(planePos,planeNorm,内点[0],外点[1]);
顶点。添加(newVert1);
顶点。添加(newVert2);
//三角形存储为顶点参照,而不是实际的顶点对象。
三角形温度=新三角形(t.getVertKeys()[0],顶点.size()-2,顶点.size()-1,顶点);
温度设置颜色(1,0,0,t.getBrightness(),t.getAlpha());
三角形。添加(临时);
继续;
}
//三角形内部有两个点删除原始添加两个新剪裁的三角形
如果(insidePointCount==2){
t、 dontDraw();
顶点newVert1=向量相交平面(planePos,planeNorm,内点[0],外点[0]);
顶点newVert2=向量相交平面(planePos,planeNorm,内点[1],外点[0]);
顶点。添加(newVert1);
顶点。添加(newVert2);
三角形温度=新三角形(t.getVertKeys()[0],t.getVertKeys()[1],顶点.size()-1,顶点);
温度设置颜色(0,1,0,t.getBrightness(),t.getAlpha());
三角形。添加(临时);
temp=新三角形(t.getVertKeys()[0],t.getVertKeys()[1],顶点.size()-2,顶点);
温度设置颜色(0,0,1,t.getBrightness(),t.getAlpha());
三角形。添加(临时);
继续;
}
}
}

我解决了问题,新剪裁的三角形没有得到正确的顶点引用。他们只是被赋予三角形的第一个顶点,不管它是否在视图中。

我发现了问题,新剪裁的三角形没有被赋予正确的顶点引用。它们只是被赋予三角形的第一个顶点,而不管它是否在视图中。

在向量相交平面中有一个“被零除”的势