Exemple #1
0
        //---------------------------------PRIVATES-------------------------------------//

        /**
         * Sets an end as vertex (starting point if none end were defined, ending point otherwise)
         *
         * @param vertex the vertex that is an segment end
         * @return false if all the ends were already defined, true otherwise
         */
        private bool SetVertex(Vertex vertex)
        {
            //none end were defined - define starting point as VERTEX
            if (index == 0)
            {
                startVertex = vertex;
                startType   = VERTEX;
                StartDist   = line.ComputePointToPointDistance(vertex.GetPosition());
                startPos    = startVertex.GetPosition();
                index++;
                return(true);
            }
            //starting point were defined - define ending point as VERTEX
            if (index == 1)
            {
                endVertex = vertex;
                endType   = VERTEX;
                endDist   = line.ComputePointToPointDistance(vertex.GetPosition());
                endPos    = endVertex.GetPosition();
                index++;

                //defining middle based on the starting point
                //VERTEX-VERTEX-VERTEX
                if (startVertex.Equals(endVertex))
                {
                    middleType = VERTEX;
                }
                //VERTEX-EDGE-VERTEX
                else if (startType == VERTEX)
                {
                    middleType = EDGE;
                }

                //the ending point distance should be smaller than  starting point distance
                if (StartDist > endDist)
                {
                    SwapEnds();
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #2
0
        //---------------------------------PRIVATES-------------------------------------//

        /**
         * Sets an end as vertex (starting point if none end were defined, ending point otherwise)
         *
         * @param vertex the vertex that is an segment end
         * @return false if all the ends were already defined, true otherwise
         */
        private bool SetVertex(Vertex vertex)
        {
            //none end were defined - define starting point as VERTEX
            if (NumEndsSet == 0)
            {
                StartVertex   = vertex;
                StartType     = VERTEX;
                StartDistance = line.ComputePointToPointDistance(vertex.Position);
                StartPosition = StartVertex.Position;
                NumEndsSet++;
                return(true);
            }
            //starting point were defined - define ending point as VERTEX
            if (NumEndsSet == 1)
            {
                EndVertex   = vertex;
                EndType     = VERTEX;
                EndDistance = line.ComputePointToPointDistance(vertex.Position);
                EndPosition = EndVertex.Position;
                NumEndsSet++;

                //defining middle based on the starting point
                //VERTEX-VERTEX-VERTEX
                if (StartVertex.Equals(EndVertex))
                {
                    IntermediateType = VERTEX;
                }
                //VERTEX-EDGE-VERTEX
                else if (StartType == VERTEX)
                {
                    IntermediateType = EDGE;
                }

                //the ending point distance should be smaller than  starting point distance
                if (StartDistance > EndDistance)
                {
                    SwapEnds();
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #3
0
        //---------------------------------PRIVATES-------------------------------------//

        /**
         * Sets an end as vertex (starting point if none end were defined, ending point otherwise)
         *
         * @param vertex the vertex that is an segment end
         * @return false if all the ends were already defined, true otherwise
         */
        private bool SetVertex(Vertex vertex)
        {
            //none end were defined - define starting point as VERTEX
            if (_Index == 0)
            {
                _StartVertex = vertex;
                _StartType   = VERTEX;
                StartDist    = Line.ComputePointToPointDistance(vertex.Position);
                _StartPos    = _StartVertex.Position;
                _Index++;
                return(true);
            }
            //starting point were defined - define ending point as VERTEX
            if (_Index == 1)
            {
                _EndVertex = vertex;
                _EndType   = VERTEX;
                _EndDist   = Line.ComputePointToPointDistance(vertex.Position);
                _EndPos    = _EndVertex.Position;
                _Index++;

                //defining middle based on the starting point
                //VERTEX-VERTEX-VERTEX
                if (_StartVertex.Equals(_EndVertex))
                {
                    _MiddleType = VERTEX;
                }
                //VERTEX-EDGE-VERTEX
                else if (_StartType == VERTEX)
                {
                    _MiddleType = EDGE;
                }

                //the ending point distance should be smaller than  starting point distance
                if (StartDist > _EndDist)
                {
                    SwapEnds();
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #4
0
        /// <summary>
        /// Classifies the face based on the ray trace technique
        /// </summary>
        /// <param name="obj">object3d used to compute the face status</param>
        public void RayTraceClassify(Object3D obj)
        {
            //creating a ray starting at the face baricenter going to the normal direction
            Line ray = new Line(GetNormal(), center);

            bool    success;
            double  distance;
            Vector3 intersectionPoint;
            Face    closestFace = null;
            double  closestDistance;

            do
            {
                success         = true;
                closestDistance = Double.MaxValue;
                //for each face from the other solid...
                for (int faceIndex = 0; faceIndex < obj.GetNumFaces(); faceIndex++)
                {
                    Face face = obj.GetFace(faceIndex);
                    intersectionPoint = ray.ComputePlaneIntersection(face.GetPlane());

                    //if ray intersects the plane...
                    if (intersectionPoint.x != double.PositiveInfinity)
                    {
                        double dotProduct = Vector3.Dot(face.GetNormal(), ray.Direction);
                        distance = ray.ComputePointToPointDistance(intersectionPoint);

                        //if ray lies in plane...
                        if (Math.Abs(distance) < EqualityTolerance && Math.Abs(dotProduct) < EqualityTolerance)
                        {
                            //disturb the ray in order to not lie into another plane
                            ray.PerturbDirection();
                            success = false;
                            break;
                        }

                        //if ray starts in plane...
                        if (Math.Abs(distance) < EqualityTolerance && Math.Abs(dotProduct) > EqualityTolerance)
                        {
                            //if ray intersects the face...
                            if (face.ContainsPoint(intersectionPoint))
                            {
                                //faces coincide
                                closestFace     = face;
                                closestDistance = 0;
                                break;
                            }
                        }

                        //if ray intersects plane...
                        else if (Math.Abs(dotProduct) > EqualityTolerance && distance > EqualityTolerance)
                        {
                            if (distance < closestDistance)
                            {
                                //if ray intersects the face;
                                if (face.ContainsPoint(intersectionPoint))
                                {
                                    //this face is the closest face until now
                                    closestDistance = distance;
                                    closestFace     = face;
                                }
                            }
                        }
                    }
                }
            } while (success == false);


            if (closestFace == null)
            {
                //none face found: outside face
                status = Status.OUTSIDE;
            }
            else             //face found: test dot product
            {
                double dotProduct = Vector3.Dot(closestFace.GetNormal(), ray.Direction);

                //distance = 0: coplanar faces
                if (Math.Abs(closestDistance) < EqualityTolerance)
                {
                    if (dotProduct > EqualityTolerance)
                    {
                        status = Status.SAME;
                    }
                    else if (dotProduct < -EqualityTolerance)
                    {
                        status = Status.OPPOSITE;
                    }
                }
                else if (dotProduct > EqualityTolerance)
                {
                    //dot product > 0 (same direction): inside face
                    status = Status.INSIDE;
                }
                else if (dotProduct < -EqualityTolerance)
                {
                    //dot product < 0 (opposite direction): outside face
                    status = Status.OUTSIDE;
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// 为表面分类,基于光线追踪技术
        /// </summary>
        /// <param name="obj">计算面状态的 3D 物件</param>
        public void RayTraceClassify(Object3D obj)
        {
            Line   ray         = new Line(PlaneNormal, Center); // 射线从面的几何中心发出,方向为法线方向
            Face   closet      = default;
            bool   foundCloset = false;
            double closestDistance;
            bool   success;

            do
            {
                success         = true;
                closestDistance = double.MaxValue;
                for (int faceIndex = 0; faceIndex < obj.GetNumFaces(); faceIndex++)
                {
                    Face face = obj.GetFace(faceIndex);
                    var  intersectionPoint = ray.ComputePlaneIntersection(face.Plane); // 对三角面所在的平面采样
                    if (intersectionPoint.x < float.PositiveInfinity)                  // 射线被平面拦截
                    {
                        var  distance = ray.ComputePointToPointDistance(intersectionPoint);
                        var  dot      = Vector3Double.Dot(face.PlaneNormal, ray.Direction);
                        bool parallel = Math.Abs(dot) < epsilon; // 射线与平面平行
                        //if ray lies in plane...
                        if (Math.Abs(distance) < epsilon)        // 交点是射线起点
                        {
                            if (parallel)
                            {
                                // 略微抖动光线方向以免采样到另一平面
                                ray.PerturbDirection();
                                success = false;
                                break;
                            }
                            else if (face.ContainsPoint(intersectionPoint))
                            {
                                // 面重合
                                closet          = face;
                                foundCloset     = true;
                                closestDistance = 0;
                                break;
                            }
                        }
                        else if (!parallel && distance > epsilon)  // 射线产生交点
                        {
                            if (distance < closestDistance && face.ContainsPoint(intersectionPoint))
                            {
                                closestDistance = distance;
                                closet          = face; // 当前的面时最近的平面
                                foundCloset     = true;
                            }
                        }
                    }
                }
            } while (!success);

            if (!foundCloset)
            {
                Status = Status.OUTSIDE;
            }                                               // 没有找到面,自己是外部面
            else // 由离自己最近的面,检查方向
            {
                var dot = Vector3Double.Dot(closet.PlaneNormal, ray.Direction);
                if (Math.Abs(closestDistance) < epsilon)  // 距离为零,这个面和自己重合
                {
                    if (dot > epsilon)
                    {
                        Status = Status.SAME;
                    }
                    else if (dot < -epsilon)
                    {
                        Status = Status.OPPOSITE;
                    }
                }
                else if (dot > epsilon)
                {
                    Status = Status.INSIDE;
                }                                                    // 不重合,同向,在参数物件内部
                else if (dot < -epsilon)
                {
                    Status = Status.OUTSIDE;
                }                                                      // 不重合,反向,在参数物件外部
            }
        }