/// <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); }