将CombinedGeometry路径转换为多边形

时间:2013-09-14 00:39:40

标签: c# wpf path polygon

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

    }
}

&LT;&LT;一些图像更新:&gt;&gt;

这是要减去的2个形状:

enter image description here

这就是我作为一条道路所得到的: enter image description here

这就是我得到的Polygon: enter image description here

不确定为什么点数列表超过20分。还是不知所措。

&LT;&LT;更新&gt;&gt;     将转换代码更改为此,但它是一个包含一个起点和一个终点的多边形。

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

1 个答案:

答案 0 :(得分: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);
}