我有这段代码可以使用组合几何添加两个形状,这可以很好地创建路径对象。我正在尝试将路径转换为多边形,这适用于矩形,但不适用于椭圆。我在下面用 // Conversion Here ******** 标记了我要转换为多边形的新部分
如果有人能告诉我为什么这不适用于椭圆以及我如何使它适用于所有形状,我将不胜感激。
这是代码:
public void AddShapes()
{
try
{
double ZOrderNum = 2000;
FrameworkElement elementMain = new FrameworkElement();
List<double> lstZOrders = new List<double>();
//Get the Back index
foreach (FrameworkElement feObject in MainWindow.Data.SelectedObjects)
{
lstZOrders.Add(Canvas.GetZIndex(feObject));
if (Canvas.GetZIndex(feObject) < ZOrderNum)
{
ZOrderNum = Canvas.GetZIndex(feObject);
elementMain = feObject;
}
}
int TotalElements = MainWindow.Data.SelectedObjects.Count;
FrameworkElement feMain = elementMain;
TranslateTransform transMain = new TranslateTransform();
TranslateTransform transSubtract = new TranslateTransform();
RectangleGeometry geomMainRect = new RectangleGeometry();
RectangleGeometry geomSubtractRect = new RectangleGeometry();
EllipseGeometry geomMainEllipse = new EllipseGeometry();
EllipseGeometry geomSubtractEllipse = new EllipseGeometry();
PathGeometry geomMainPath = new PathGeometry();
PathGeometry geomSubtractPath = new PathGeometry();
LineGeometry geomMainLine = new LineGeometry();
LineGeometry geomSubtractLine = new LineGeometry();
GeometryGroup geomGroup = new GeometryGroup();
//Main Geometry
transMain = feMain.RenderTransform as TranslateTransform;
if (feMain is Rectangle)
{
geomMainRect = new RectangleGeometry(new Rect(0, 0, feMain.Width, feMain.Height));
}
if (feMain is Ellipse)
{
geomMainEllipse = new EllipseGeometry(new Rect(0, 0, feMain.Width, feMain.Height));
}
if (feMain is Canvas)
{
Canvas canvasPath = feMain as Canvas;
if (canvasPath.Children.Count > 0)
{
if (canvasPath.Children[0] is Path)
{
Path pathMain = canvasPath.Children[0] as Path;
geomMainPath = pathMain.Data.GetFlattenedPathGeometry();
}
if (canvasPath.Children[0] is Polygon)
{
Polygon pathMain = canvasPath.Children[0] as Polygon;
geomMainPath = PolygonGemoetry(pathMain);
}
}
}
TranslateTransform transCheckSub = new TranslateTransform(2000, 2000);
foreach (FrameworkElement feObject in MainWindow.Data.SelectedObjects)
{
if (feObject != feMain)
{
//Add to Subtract Geometry Group
transSubtract = feObject.RenderTransform as TranslateTransform;
if (transCheckSub.X < transSubtract.X)
{
transCheckSub.X = transSubtract.X;
}
if (transCheckSub.Y < transSubtract.Y)
{
transCheckSub.Y = transSubtract.Y;
}
transCheckSub = transSubtract;
if (feObject is Rectangle)
{
geomSubtractRect = new RectangleGeometry(new Rect(transSubtract.X - transMain.X, transSubtract.Y - transMain.Y, feObject.Width, feObject.Height));
geomGroup.Children.Add(geomSubtractRect);
}
if (feObject is Ellipse)
{
geomSubtractEllipse = new EllipseGeometry(new Rect(transSubtract.X - transMain.X, transSubtract.Y - transMain.Y, feObject.Width, feObject.Height));
geomGroup.Children.Add(geomSubtractEllipse);
}
if (feObject is Line)
{
Line line = feObject as Line;
geomSubtractLine = new LineGeometry(new Point(line.X1, line.Y1), new Point(line.X2, line.Y2));
geomGroup.Children.Add(geomSubtractLine);
}
if (feObject is Canvas)
{
Canvas canvasPath = feObject as Canvas;
if (canvasPath.Children.Count > 0)
{
if (canvasPath.Children[0] is Path)
{
Path pathSubtract = canvasPath.Children[0] as Path;
geomSubtractPath = pathSubtract.Data.GetFlattenedPathGeometry();
geomGroup.Children.Add(geomSubtractPath);
}
if (canvasPath.Children[0] is Polygon)
{
Polygon pathSubtract = canvasPath.Children[0] as Polygon;
geomSubtractPath = PolygonGemoetrySubtract(pathSubtract, transMain, transSubtract);
geomGroup.Children.Add(geomSubtractPath);
}
}
}
}
}
//Put it all together
CombinedGeometry cg = new CombinedGeometry();
cg.GeometryCombineMode = GeometryCombineMode.Union;
//Main Background Paths
if (geomMainRect.Bounds.Width > 0)
{
cg.Geometry1 = geomMainRect;
}
if (geomMainEllipse.Bounds.Width > 0)
{
cg.Geometry1 = geomMainEllipse;
}
if (geomMainPath.Bounds.Width > 0)
{
cg.Geometry1 = geomMainPath;
}
//Subtract Paths
cg.Geometry2 = geomGroup;
geomGroup.FillRule = FillRule.EvenOdd;
System.Windows.Shapes.Path myPath = new System.Windows.Shapes.Path();
myPath.Data = cg;
if (feMain is Rectangle)
{
Rectangle rect = feMain as Rectangle;
myPath.Fill = rect.Fill;
myPath.Stroke = rect.Stroke;
myPath.StrokeThickness = rect.StrokeThickness;
}
if (feMain is Ellipse)
{
Ellipse rect = feMain as Ellipse;
myPath.Fill = rect.Fill;
myPath.Stroke = rect.Stroke;
myPath.StrokeThickness = rect.StrokeThickness;
}
if (feMain is Canvas)
{
Canvas canvasPath = feMain as Canvas;
if (canvasPath.Children.Count > 0)
{
if (canvasPath.Children[0] is Path)
{
Path rect = canvasPath.Children[0] as Path;
myPath.Fill = rect.Fill;
myPath.Stroke = rect.Stroke;
myPath.StrokeThickness = rect.StrokeThickness;
}
if (canvasPath.Children[0] is Polygon)
{
Polygon rect = canvasPath.Children[0] as Polygon;
myPath.Fill = rect.Fill;
myPath.Stroke = rect.Stroke;
myPath.StrokeThickness = rect.StrokeThickness;
}
}
}
myPath.Name = "NewPath";
myPath.Name = "Object" + MainWindow.Data.TotalObjects.ToString();
myPath.Uid = "Object" + MainWindow.Data.TotalObjects.ToString() + "-" + MainWindow.Data.NewZIndex.ToString();
myPath.Tag = "No";
Canvas canvas = new Canvas();
canvas.Name = "Object" + MainWindow.Data.TotalObjects.ToString();
canvas.Uid = "Object" + MainWindow.Data.TotalObjects.ToString() + "-" + MainWindow.Data.NewZIndex.ToString();
canvas.Tag = "No";
canvas.Width = myPath.Data.Bounds.Width;
canvas.Height = myPath.Data.Bounds.Height;
//Get the left and top most transforms
canvas.RenderTransform = transMain;
// canvas.Children.Add(myPath);
// Conversion Here ************** Convert the path to Polygon ***************************
if (myPath.Data.GetFlattenedPathGeometry().Figures[0].Segments[0] is PolyLineSegment)
{
List<Point> pc = new List<Point>();
pc.Add(myPath.Data.GetFlattenedPathGeometry().Figures[0].StartPoint);
pc.AddRange((myPath.Data.GetFlattenedPathGeometry().Figures[0].Segments[0] as PolyLineSegment).Points);
Polygon pGon = new Polygon();
pGon.Fill = myPath.Fill;
pGon.StrokeThickness = myPath.StrokeThickness;
pGon.Stroke = myPath.Stroke;
foreach (Point pt in pc)
{
pGon.Points.Add(pt);
}
//pGon.Points = pc;
canvas.Children.Add(pGon);
}
MainWindow.Data.NewZIndex++;
MainWindow.Data.TotalObjects++;
//Add a Scale Transform for resizing
ScaleTransform scale = new ScaleTransform(1, 1);
myPath.RenderTransform = scale;
//Add the new Path
MainWindow.Data.canvasDrawing[MainWindow.Data.CurrentFrame].Children.Add(canvas);
//Clean Up
MainWindow.Data.canvasDrawing[MainWindow.Data.CurrentFrame].Children.Remove(feMain);
for (int i = 0; i < MainWindow.Data.SelectedObjects.Count; i++)
{
FrameworkElement feObject = MainWindow.Data.SelectedObjects[i];
MainWindow.Data.canvasDrawing[MainWindow.Data.CurrentFrame].Children.Remove(feObject);
}
MainWindow.SelectActions.DeselectAllObjects();
}
catch (Exception ex)
{
}
}
<< 部分图片更新:>>
这是要减去的 2 个形状:
这就是我得到的路径:
这就是我作为多边形得到的:
不知道为什么当点列表有超过 20 点。还是不知所措。
<< 更新>> 将转换代码更改为这个,但它是一个多边形,一个起点和一个终点。
//Convert Path to Polygon
List<Point> pc = new List<Point>();
PathGeometry g = myPath.Data.GetFlattenedPathGeometry();
foreach (var f in g.Figures)
foreach (var s in f.Segments)
if (s is PolyLineSegment)
foreach (var pt in ((PolyLineSegment)s).Points)
{
pc.Add(pt);
}
Polyline pGon = new Polyline();
pGon.Fill = myPath.Fill;
pGon.StrokeThickness = myPath.StrokeThickness;
pGon.Stroke = myPath.Stroke;
foreach (Point pt in pc)
{
pGon.Points.Add(pt);
}
canvas.Children.Add(pGon);