1

我有这段代码可以使用组合几何添加两个形状,这可以很好地创建路径对象。我正在尝试将路径转换为多边形,这适用于矩形,但不适用于椭圆。我在下面用 // 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);
4

1 回答 1

2

以下方法将 PathFigure 中 PolyLineSegments 中的所有点复制到单个 PointCollection 中。

using System.Linq;
...

private static PointCollection GetPolylinePoints(PathFigure figure)
{
    var points = new PointCollection();
    points.Add(figure.StartPoint);

    foreach (var segment in figure.Segments.OfType<PolyLineSegment>())
    {
        foreach (var point in segment.Points)
        {
            points.Add(point);
        }
    }

    return points;
}

现在您可以从 GetFlattenedPathGeometry 返回的 PathGeometry 创建一组多边形,如下所示:

var geometry = myPath.Data.GetFlattenedPathGeometry();

foreach (var figure in geometry.Figures)
{
    var polyline = new Polygon
    {
        Fill = myPath.Fill,
        Stroke = myPath.Stroke,
        StrokeThickness = myPath.StrokeThickness,
        Points = GetPolylinePoints(figure)
    };

    canvas.Children.Add(polyline);
}
于 2013-09-14T10:02:03.373 回答