Пример #1
0
        private HalfEdge addAdjoiningFace(Vertex eyeVtx, HalfEdge he)
        {
            Face face = Face.createTriangle(eyeVtx, he.tail(), he.head());

            faces.Add(face);
            face.getEdge(-1).setOpposite(he.getOpposite());
            return(face.getEdge(0));
        }
Пример #2
0
        protected void createInitialSimplex()
        {
            double max  = 0;
            int    imax = 0;

            for (int i = 0; i < 3; i++)
            {
                double diff = maxVtxs[i].pnt.get(i) - minVtxs[i].pnt.get(i);
                if (diff > max)
                {
                    max  = diff;
                    imax = i;
                }
            }

            if (max <= tolerance)
            {
                throw new Exception("Input points appear to be coincident");
            }
            Vertex[] vtx = new Vertex[4];
            // set first two vertices to be those with the greatest
            // one dimensional separation

            vtx[0] = maxVtxs[imax];
            vtx[1] = minVtxs[imax];
            // set third vertex to be the vertex farthest from
            // the line between vtx0 and vtx1
            Vector3d u01    = new Vector3d();
            Vector3d diff02 = new Vector3d();
            Vector3d nrml   = new Vector3d();
            Vector3d xprod  = new Vector3d();
            double   maxSqr = 0;

            u01.sub(vtx[1].pnt, vtx[0].pnt);
            u01.normalize();
            for (int i = 0; i < numPoints; i++)
            {
                diff02.sub(pointBuffer[i].pnt, vtx[0].pnt);
                xprod.cross(u01, diff02);
                double lenSqr = xprod.normSquared();
                if (lenSqr > maxSqr &&
                    pointBuffer[i] != vtx[0] && // paranoid
                    pointBuffer[i] != vtx[1])
                {
                    maxSqr = lenSqr;
                    vtx[2] = pointBuffer[i];
                    nrml.set(xprod);
                }
            }
            if (Math.Sqrt(maxSqr) <= 100 * tolerance)
            {
                throw new Exception("Input points appear to be colinear");
            }
            nrml.normalize();


            double maxDist = 0;
            double d0      = vtx[2].pnt.dot(nrml);

            for (int i = 0; i < numPoints; i++)
            {
                double dist = Math.Abs(pointBuffer[i].pnt.dot(nrml) - d0);
                if (dist > maxDist &&
                    pointBuffer[i] != vtx[0] && // paranoid
                    pointBuffer[i] != vtx[1] &&
                    pointBuffer[i] != vtx[2])
                {
                    maxDist = dist;
                    vtx[3]  = pointBuffer[i];
                }
            }
            if (Math.Abs(maxDist) <= 100 * tolerance)
            {
                throw new Exception("Input points appear to be coplanar");
            }

            Face[] tris = new Face[4];

            if (vtx[3].pnt.dot(nrml) - d0 < 0)
            {
                tris[0] = Face.createTriangle(vtx[0], vtx[1], vtx[2]);
                tris[1] = Face.createTriangle(vtx[3], vtx[1], vtx[0]);
                tris[2] = Face.createTriangle(vtx[3], vtx[2], vtx[1]);
                tris[3] = Face.createTriangle(vtx[3], vtx[0], vtx[2]);

                for (int i = 0; i < 3; i++)
                {
                    int k = (i + 1) % 3;
                    tris[i + 1].getEdge(1).setOpposite(tris[k + 1].getEdge(0));
                    tris[i + 1].getEdge(2).setOpposite(tris[0].getEdge(k));
                }
            }
            else
            {
                tris[0] = Face.createTriangle(vtx[0], vtx[2], vtx[1]);
                tris[1] = Face.createTriangle(vtx[3], vtx[0], vtx[1]);
                tris[2] = Face.createTriangle(vtx[3], vtx[1], vtx[2]);
                tris[3] = Face.createTriangle(vtx[3], vtx[2], vtx[0]);

                for (int i = 0; i < 3; i++)
                {
                    int k = (i + 1) % 3;
                    tris[i + 1].getEdge(0).setOpposite(tris[k + 1].getEdge(1));
                    tris[i + 1].getEdge(2).setOpposite(tris[0].getEdge((3 - i) % 3));
                }
            }
            for (int i = 0; i < 4; i++)
            {
                faces.Add(tris[i]);
            }

            for (int i = 0; i < numPoints; i++)
            {
                Vertex v = pointBuffer[i];

                if (v == vtx[0] || v == vtx[1] || v == vtx[2] || v == vtx[3])
                {
                    continue;
                }

                maxDist = tolerance;
                Face maxFace = null;
                for (int k = 0; k < 4; k++)
                {
                    double dist = tris[k].distanceToPlane(v.pnt);
                    if (dist > maxDist)
                    {
                        maxFace = tris[k];
                        maxDist = dist;
                    }
                }
                if (maxFace != null)
                {
                    addPointToFace(v, maxFace);
                }
            }
        }