/// <summary>
        /// Get two vectors, which indicate some edge direction which contain given point,
        /// set the given point as the start point, the other end point of the edge as end
        /// </summary>
        /// <param name="edges">polygon</param>
        /// <param name="point">a point of the polygon</param>
        /// <returns>two vectors indicate edge direction</returns>
        public static IList <Vector3d> GetRelatedVectors(IList <Line> edges, Vector3d point)
        {
            // Initialize the return vector list.
            List <Vector3d> vectors = new List <Vector3d>();

            // Get all the edge which contain this point.
            // And get the vector from this point to another point
            foreach (Line line in edges)
            {
                if (point.IsAlmostEqualTo(line.StartPoint))
                {
                    Vector3d vector = PolylineOffsetUtil.SubXYZ(line.EndPoint, line.StartPoint);
                    vectors.Add(vector);
                }
                if (point.IsAlmostEqualTo(line.EndPoint))
                {
                    Vector3d vector = PolylineOffsetUtil.SubXYZ(line.StartPoint, line.EndPoint);
                    vectors.Add(vector);
                }
            }

            // only two vector(direction) should be found
            if (2 != vectors.Count)
            {
                throw new Exception("a point on polygon should have only two direction.");
            }

            return(vectors);
        }
        public static Dictionary <Vector2d, PointRelativePos> OffsetPoints(IList <Vector2d> oriPoints, double offset)
        {
            if (PolylineOffsetUtil.IsAlmostZero(offset))
            {
                Dictionary <Vector2d, PointRelativePos> map    = OffsetPoints(oriPoints, 1.0);
                Dictionary <Vector2d, PointRelativePos> result = new Dictionary <Vector2d, PointRelativePos>();
                int i = 0;
                foreach (KeyValuePair <Vector2d, PointRelativePos> keyValue in map)
                {
                    result.Add(oriPoints[i++], keyValue.Value);
                }

                return(result);
            }

            // Initialize the offset point list.
            Dictionary <Vector2d, PointRelativePos> points = new Dictionary <Vector2d, PointRelativePos>();
            IList <Vector3d> oriPointsVector3d             = PolylineOffsetUtil.Inflatten(oriPoints);
            IList <Line>     lineList = PolylineOffsetUtil.ChangeProfilePointListToLine(oriPointsVector3d);

            // Get all points of the swept profile, and offset it in two related direction
            foreach (Vector3d point in oriPointsVector3d)
            {
                // Get two related directions
                IList <Vector3d> directions = GetRelatedVectors(lineList, point);
                Vector3d         firstDir   = directions[0];
                Vector3d         secondDir  = directions[1];

                // offset the point in two direction
                Vector3d movedPoint = PolylineOffsetUtil.OffsetPoint(point, firstDir, offset);
                movedPoint = PolylineOffsetUtil.OffsetPoint(movedPoint, secondDir, offset);

                PointRelativePos posFlag       = PointRelativePos.Inner;
                Vector2d         pointVector2d = PolylineOffsetUtil.Flatten(movedPoint);
                if (offset > 0)
                {
                    if (!(PolygonContains(oriPoints, pointVector2d)))
                    {
                        movedPoint = PolylineOffsetUtil.OffsetPoint(point, firstDir, offset * -1.0);
                        movedPoint = PolylineOffsetUtil.OffsetPoint(movedPoint, secondDir, offset * -1.0);

                        posFlag = PointRelativePos.Outer;
                    }
                }
                else
                {
                    if (PolygonContains(oriPoints, pointVector2d))
                    {
                        movedPoint = PolylineOffsetUtil.OffsetPoint(point, firstDir, offset * -1.0);
                        movedPoint = PolylineOffsetUtil.OffsetPoint(movedPoint, secondDir, offset * -1.0);

                        posFlag = PointRelativePos.Outer;
                    }
                }

                // add the offset point into the array
                points.Add(new Vector2d(movedPoint.x, movedPoint.y), posFlag);
            }

            return(points);
        }