我在WPF中解决了这个问题 . 我想要一个可以用曲线和孔做复杂形状的解决方案 . 我得到的最接近的是在原始形状上使用GetFlattenedPathGeometry,它将曲线转换为线段,然后运行上述方法 . 这是一个冗余的计算,但结合平行四边形,然后在起点和终点“压印”原始形状导致最终几何中的几何形状相对较少 .
public Geometry translateGeo(Geometry baseGeo, Point translate)
{
// sweeps a geometry linearly from current location through vector
Debug.WriteLine("Translating Geometry");
Debug.WriteLine("Original Outline Verticies: " + CountVerticies(baseGeo.GetFlattenedPathGeometry()));
Geometry sweptPathGeo = baseGeo.Clone();
Geometry capGeo = baseGeo.Clone();
capGeo.Transform = new TranslateTransform(translate.X, translate.Y);
sweptPathGeo = new CombinedGeometry(GeometryCombineMode.Union, sweptPathGeo, capGeo);
sweptPathGeo = sweptPathGeo.GetFlattenedPathGeometry();
geometry = sweptPathGeo.Clone();
PathGeometry pathGeo = baseGeo.GetFlattenedPathGeometry();
foreach (PathFigure figure in pathGeo.Figures)
{
Point startPoint = figure.StartPoint;
//Debug.WriteLine(startPoint.X + ", " + startPoint.Y);
foreach (PathSegment segment in figure.Segments)
{
PolyLineSegment polySegment = segment as PolyLineSegment;
if (polySegment != null)
{
foreach (Point point in polySegment.Points)
{
sweptPathGeo = new CombinedGeometry(GeometryCombineMode.Union, sweptPathGeo, getShadow(startPoint, point, translate));
startPoint = point;
}
}
LineSegment lineSegment = segment as LineSegment;
if (lineSegment != null)
{
sweptPathGeo = new CombinedGeometry(GeometryCombineMode.Union, sweptPathGeo, getShadow(startPoint, lineSegment.Point, translate));
startPoint = lineSegment.Point;
}
}
}
//sweptPathGeo = sweptPathGeo.GetOutlinedPathGeometry();
Debug.WriteLine("Finale Outline Verticies: " + CountVerticies(sweptPathGeo.GetFlattenedPathGeometry()));
return sweptPathGeo;
}
public Geometry getShadow(Point startPoint, Point endPoint, Point translate)
{
PointCollection points = new PointCollection();
points.Add(startPoint);
points.Add(endPoint);
points.Add(new Point(endPoint.X + translate.X, endPoint.Y + translate.Y));
points.Add(new Point(startPoint.X + translate.X, startPoint.Y + translate.Y));
points.Add(startPoint);
Polygon poly = new Polygon();
poly.Points = points;
poly.Arrange(geometry.Bounds);
poly.Measure(geometry.Bounds.Size);
PathGeometry returnGeo = poly.RenderedGeometry.GetOutlinedPathGeometry();
return returnGeo;
//foreach (Point point in points) Debug.WriteLine(point.X + ", " + point.Y);
}
private int CountVerticies(PathGeometry geo)
{
int verticies = 0;
foreach (PathFigure figure in geo.Figures)
{
Point startPoint = figure.StartPoint;
verticies += 1;
foreach (PathSegment segment in figure.Segments)
{
PolyLineSegment polySegment = segment as PolyLineSegment;
if (polySegment != null) verticies += polySegment.Points.Count;
LineSegment lineSegment = segment as LineSegment;
if (lineSegment != null) verticies += 1;
}
}
return verticies;
}