Exemple #1
0
 //------------------------------------OTHERS------------------------------------//
 /**
  * Checks if two segments intersect
  *
  * @param segment the other segment to check the intesection
  * @return true if the segments intersect, false otherwise
  */
 public bool intersect(Segment segment)
 {
     if (endDist < segment.startDist + TOL || segment.endDist < startDist + TOL)
     {
         return false;
     }
     else
     {
         return true;
     }
 }
Exemple #2
0
        /**
         * Split an individual face
         *
         * @param facePos face position on the array of faces
         * @param segment1 segment representing the intersection of the face with the plane
         * of another face
         * @return segment2 segment representing the intersection of other face with the
         * plane of the current face plane
         */
        private void splitFace(int facePos, Segment segment1, Segment segment2)
        {
            Vertex startPosVertex, endPosVertex;
            Point3d startPos, endPos;
            int startType, endType, middleType;
            double startDist, endDist;

            Face face = getFace(facePos);
            Vertex startVertex = segment1.getStartVertex();
            Vertex endVertex = segment1.getEndVertex();

            //starting point: deeper starting point
            if (segment2.getStartDistance() > segment1.getStartDistance() + TOL)
            {
                startDist = segment2.getStartDistance();
                startType = segment1.getIntermediateType();
                startPos = segment2.getStartPosition();
            }
            else
            {
                startDist = segment1.getStartDistance();
                startType = segment1.getStartType();
                startPos = segment1.getStartPosition();
            }

            //ending point: deepest ending point
            if (segment2.getEndDistance() < segment1.getEndDistance() - TOL)
            {
                endDist = segment2.getEndDistance();
                endType = segment1.getIntermediateType();
                endPos = segment2.getEndPosition();
            }
            else
            {
                endDist = segment1.getEndDistance();
                endType = segment1.getEndType();
                endPos = segment1.getEndPosition();
            }
            middleType = segment1.getIntermediateType();

            //set vertex to BOUNDARY if it is start type
            if (startType == Segment.VERTEX)
            {
                startVertex.setStatus(Vertex.BOUNDARY);
            }

            //set vertex to BOUNDARY if it is end type
            if (endType == Segment.VERTEX)
            {
                endVertex.setStatus(Vertex.BOUNDARY);
            }

            //VERTEX-_______-VERTEX
            if (startType == Segment.VERTEX && endType == Segment.VERTEX)
            {
                return;
            }

            //______-EDGE-______
            else if (middleType == Segment.EDGE)
            {
                //gets the edge
                int splitEdge;
                if ((startVertex == face.v1 && endVertex == face.v2) || (startVertex == face.v2 && endVertex == face.v1))
                {
                    splitEdge = 1;
                }
                else if ((startVertex == face.v2 && endVertex == face.v3) || (startVertex == face.v3 && endVertex == face.v2))
                {
                    splitEdge = 2;
                }
                else
                {
                    splitEdge = 3;
                }

                //VERTEX-EDGE-EDGE
                if (startType == Segment.VERTEX)
                {
                    breakFaceInTwo(facePos, endPos, splitEdge);
                    return;
                }

                    //EDGE-EDGE-VERTEX
                    else if (endType == Segment.VERTEX)
                {
                    breakFaceInTwo(facePos, startPos, splitEdge);
                    return;
                }

                    // EDGE-EDGE-EDGE
                    else if (startDist == endDist)
                {
                    breakFaceInTwo(facePos, endPos, splitEdge);
                }
                else
                {
                    if ((startVertex == face.v1 && endVertex == face.v2) || (startVertex == face.v2 && endVertex == face.v3) || (startVertex == face.v3 && endVertex == face.v1))
                    {
                        breakFaceInThree(facePos, startPos, endPos, splitEdge);
                    }
                    else
                    {
                        breakFaceInThree(facePos, endPos, startPos, splitEdge);
                    }
                }
                return;
            }

            //______-FACE-______

            //VERTEX-FACE-EDGE
            else if (startType == Segment.VERTEX && endType == Segment.EDGE)
            {
                breakFaceInTwo(facePos, endPos, endVertex);
            }
            //EDGE-FACE-VERTEX
            else if (startType == Segment.EDGE && endType == Segment.VERTEX)
            {
                breakFaceInTwo(facePos, startPos, startVertex);
            }
            //VERTEX-FACE-FACE
            else if (startType == Segment.VERTEX && endType == Segment.FACE)
            {
                breakFaceInThree(facePos, endPos, startVertex);
            }
            //FACE-FACE-VERTEX
            else if (startType == Segment.FACE && endType == Segment.VERTEX)
            {
                breakFaceInThree(facePos, startPos, endVertex);
            }
            //EDGE-FACE-EDGE
            else if (startType == Segment.EDGE && endType == Segment.EDGE)
            {
                breakFaceInThree(facePos, startPos, endPos, startVertex, endVertex);
            }
            //EDGE-FACE-FACE
            else if (startType == Segment.EDGE && endType == Segment.FACE)
            {
                breakFaceInFour(facePos, startPos, endPos, startVertex);
            }
            //FACE-FACE-EDGE
            else if (startType == Segment.FACE && endType == Segment.EDGE)
            {
                breakFaceInFour(facePos, endPos, startPos, endVertex);
            }
            //FACE-FACE-FACE
            else if (startType == Segment.FACE && endType == Segment.FACE)
            {
                Vector3d segmentVector = new Vector3d(startPos.x - endPos.x, startPos.y - endPos.y, startPos.z - endPos.z);

                //if the intersection segment is a point only...
                if (Math.Abs(segmentVector.x) < TOL && Math.Abs(segmentVector.y) < TOL && Math.Abs(segmentVector.z) < TOL)
                {
                    breakFaceInThree(facePos, startPos);
                    return;
                }

                //gets the vertex more lined with the intersection segment
                int linedVertex;
                Point3d linedVertexPos;
                Vector3d vertexVector = new Vector3d(endPos.x - face.v1.x, endPos.y - face.v1.y, endPos.z - face.v1.z);
                vertexVector.normalize();
                double dot1 = Math.Abs(segmentVector.dot(vertexVector));
                vertexVector = new Vector3d(endPos.x - face.v2.x, endPos.y - face.v2.y, endPos.z - face.v2.z);
                vertexVector.normalize();
                double dot2 = Math.Abs(segmentVector.dot(vertexVector));
                vertexVector = new Vector3d(endPos.x - face.v3.x, endPos.y - face.v3.y, endPos.z - face.v3.z);
                vertexVector.normalize();
                double dot3 = Math.Abs(segmentVector.dot(vertexVector));
                if (dot1 > dot2 && dot1 > dot3)
                {
                    linedVertex = 1;
                    linedVertexPos = face.v1.getPosition();
                }
                else if (dot2 > dot3 && dot2 > dot1)
                {
                    linedVertex = 2;
                    linedVertexPos = face.v2.getPosition();
                }
                else
                {
                    linedVertex = 3;
                    linedVertexPos = face.v3.getPosition();
                }

                // Now find which of the intersection endpoints is nearest to that vertex.
                if (linedVertexPos.distance(startPos) > linedVertexPos.distance(endPos))
                {
                    breakFaceInFive(facePos, startPos, endPos, linedVertex);
                }
                else
                {
                    breakFaceInFive(facePos, endPos, startPos, linedVertex);
                }
            }
        }
Exemple #3
0
        //-----------------------------------OVERRIDES----------------------------------//
        /**
         * Clones the Segment object
         *
         * @return cloned Segment object
         */
        public Segment Clone()
        {
            Segment clone = new Segment();
            clone.line = line.Clone();
            clone.index = index;
            clone.startDist = startDist;
            clone.endDist = endDist;
            clone.startDist = startType;
            clone.middleType = middleType;
            clone.endType = endType;
            clone.startVertex = startVertex.Clone();
            clone.endVertex = endVertex.Clone();
            clone.startPos = startPos.Clone();
            clone.endPos = endPos.Clone();

            return clone;
        }
Exemple #4
0
        //-------------------------FACES_SPLITTING_METHODS------------------------------//
        /**
         * Split faces so that none face is intercepted by a face of other object
         *
         * @param object the other object 3d used to make the split
         */
        public void splitFaces(Object3D obj)
        {
            Line line;
            Face face1, face2;
            Segment[] segments;
            Segment segment1;
            Segment segment2;
            double distFace1Vert1, distFace1Vert2, distFace1Vert3, distFace2Vert1, distFace2Vert2, distFace2Vert3;
            int signFace1Vert1, signFace1Vert2, signFace1Vert3, signFace2Vert1, signFace2Vert2, signFace2Vert3;
            int numFacesBefore = getNumFaces();
            int numFacesStart = getNumFaces();
            int facesIgnored = 0;

            //if the objects bounds overlap...
            if (getBound().overlap(obj.getBound()))
            {
                //for each object1 face...
                for (int i = 0; i < getNumFaces(); i++)
                {
                    //if object1 face bound and object2 bound overlap ...
                    face1 = getFace(i);

                    if (face1.getBound().overlap(obj.getBound()))
                    {
                        //for each object2 face...
                        for (int j = 0; j < obj.getNumFaces(); j++)
                        {
                            //if object1 face bound and object2 face bound overlap...
                            face2 = obj.getFace(j);
                            if (face1.getBound().overlap(face2.getBound()))
                            {
                                //PART I - DO TWO POLIGONS INTERSECT?
                                //POSSIBLE RESULTS: INTERSECT, NOT_INTERSECT, COPLANAR

                                //distance from the face1 vertices to the face2 plane
                                distFace1Vert1 = computeDistance(face1.v1, face2);
                                distFace1Vert2 = computeDistance(face1.v2, face2);
                                distFace1Vert3 = computeDistance(face1.v3, face2);

                                //distances signs from the face1 vertices to the face2 plane
                                signFace1Vert1 = (distFace1Vert1 > TOL ? 1 : (distFace1Vert1 < -TOL ? -1 : 0));
                                signFace1Vert2 = (distFace1Vert2 > TOL ? 1 : (distFace1Vert2 < -TOL ? -1 : 0));
                                signFace1Vert3 = (distFace1Vert3 > TOL ? 1 : (distFace1Vert3 < -TOL ? -1 : 0));

                                //if all the signs are zero, the planes are coplanar
                                //if all the signs are positive or negative, the planes do not intersect
                                //if the signs are not equal...
                                if (!(signFace1Vert1 == signFace1Vert2 && signFace1Vert2 == signFace1Vert3))
                                {
                                    //distance from the face2 vertices to the face1 plane
                                    distFace2Vert1 = computeDistance(face2.v1, face1);
                                    distFace2Vert2 = computeDistance(face2.v2, face1);
                                    distFace2Vert3 = computeDistance(face2.v3, face1);

                                    //distances signs from the face2 vertices to the face1 plane
                                    signFace2Vert1 = (distFace2Vert1 > TOL ? 1 : (distFace2Vert1 < -TOL ? -1 : 0));
                                    signFace2Vert2 = (distFace2Vert2 > TOL ? 1 : (distFace2Vert2 < -TOL ? -1 : 0));
                                    signFace2Vert3 = (distFace2Vert3 > TOL ? 1 : (distFace2Vert3 < -TOL ? -1 : 0));

                                    //if the signs are not equal...
                                    if (!(signFace2Vert1 == signFace2Vert2 && signFace2Vert2 == signFace2Vert3))
                                    {
                                        line = new Line(face1, face2);

                                        //intersection of the face1 and the plane of face2
                                        segment1 = new Segment(line, face1, signFace1Vert1, signFace1Vert2, signFace1Vert3);

                                        //intersection of the face2 and the plane of face1
                                        segment2 = new Segment(line, face2, signFace2Vert1, signFace2Vert2, signFace2Vert3);

                                        //if the two segments intersect...
                                        if (segment1.intersect(segment2))
                                        {
                                            //PART II - SUBDIVIDING NON-COPLANAR POLYGONS
                                            int lastNumFaces = getNumFaces();
                                            this.splitFace(i, segment1, segment2);

                                            //prevent from infinite loop (with a loss of faces...)
                                            //if(numFacesStart*20<getNumFaces())
                                            //{
                                            //  System.out.println("possible infinite loop situation: terminating faces split");
                                            //  return;
                                            //}

                                            //if the face in the position isn't the same, there was a break
                                            if (face1 != getFace(i))
                                            {
                                                //if the generated solid is equal the origin...
                                                if (face1.equals(getFace(getNumFaces() - 1)))
                                                {
                                                    //return it to its position and jump it
                                                    if (i != (getNumFaces() - 1))
                                                    {
                                                        faces.RemoveAt(getNumFaces() - 1);
                                                        faces.Insert(i, face1);
                                                    }
                                                    else
                                                    {
                                                        continue;
                                                    }
                                                }
                                                                                    //else: test next face
                                                                                    else
                                                {
                                                    i--;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }