【问题标题】:WPF Modify Path Data at RuntimeWPF 在运行时修改路径数据
【发布时间】:2013-09-16 08:55:24
【问题描述】:

您好,我有一条来自 GetFlattenedPathGeometry 的路径,我可以在其中遍历图形和线段以获取要添加到 PointCollection 的点。

然后我将每个 point.x/y 乘以一个比例因子,以获得原始路径数据的完整比例版本。 (不使用 scaletransform,因为它不符合我的要求)。

如果我使用类似的东西:

public static PathGeometry GetPathGeometry(PointCollection polygonCorners)
{
    List<PathSegment> pathSegments = new List<PathSegment> { new     PolyLineSegment(polygonCorners, true) };
    PathGeometry pathGeometry = new PathGeometry();
    pathGeometry.Figures.Add(new PathFigure(polygonCorners[0], pathSegments, true));
    return pathGeometry;
} 

它返回一个新的路径几何,但不处理具有排除路径几何的椭圆,因为路径只是一条连续线。

有没有办法将 PointCollection 转换为 Path.Data(例如:使用“M”“L”等)以便我重新使用 Geometry.Parse(新字符串)?

这是我用来获取 flattenedgeometry 点集合的代码:

PathGeometry g = path.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)
            {
                strGeom += pt.ToString();
                Point ptn = new Point(pt.X * ScaleX, pt.Y * ScaleY);
                pcol.Add(ptn);
            }
        }
    }
}

这是从几何图形中减去矩形和椭圆的原始路径。

这是从代码重新创建的样子。

如果我使用原始的 GetFlattenedPathGeometry,它看起来像原始的,但我需要将点缩放到新的分辨率。

希望这会让它更清楚。

【问题讨论】:

    标签: c# wpf path geometry


    【解决方案1】:

    您可以简单地在 PathGeometry 上调用 ToString 来一次获取整个路径数据字符串:

    var sourceGeometry = path.Data.GetFlattenedPathGeometry();
    var geometryString = sourceGeometry.ToString(CultureInfo.InvariantCulture);
    var targetGeometry = Geometry.Parse(geometryString);
    

    为什么不能在调用 GetFlatnedPathGeometry 之前对整个几何体应用 ScaleTransform?以下对我来说非常有效(在排除的 CombinedGeometry 中有两个 EllipseGeometry):

    var pathGeometry = path.Data.Clone();
    pathGeometry.Transform = new ScaleTransform(0.5, 0.5);
    var scaledGeometry = pathGeometry.GetFlattenedPathGeometry();
    

    编辑:根据您在问题和 cmets 中所写的内容,我猜您实际上想要做的就是添加或组合具有不同比例因子的几何图形。如果这是真的,那么您的展平几何方法就非常复杂,因为您可以使用以下两种方法轻松做到这一点:

    private PathGeometry AddGeometries(
        Geometry geometry1, Geometry geometry2, double scale)
    {
        geometry2 = geometry2.Clone();
        geometry2.Transform = new ScaleTransform(scale, scale);
        var pathGeometry = PathGeometry.CreateFromGeometry(geometry1);
        pathGeometry.AddGeometry(geometry2);
        return pathGeometry;
    }
    
    private PathGeometry CombineGeometries(
        Geometry geometry1, Geometry geometry2, GeometryCombineMode mode, double scale)
    {
        geometry2 = geometry2.Clone();
        geometry2.Transform = new ScaleTransform(scale, scale);
        return Geometry.Combine(geometry1, geometry2, mode, null);
    }
    

    给定一个在其 Data 属性中包含一些几何图形的路径,您现在可以通过如下调用添加(或组合)一个具有缩放因子的任意其他几何图形:

    Geometry newGeometry1 = ...
    double scale1 = ...
    path.Data = AddGeometries(path.Data, newGeometry1, scale1);
    
    Geometry newGeometry2 = ...
    double scale2 = ...
    path.Data = CombineGeometries(path.Data, newGeometry2,
                GeometryCombineMode.Exclude, scale2);
    

    【讨论】:

    • 谢谢克莱门斯。感谢你的帮助。我会试试这个。尽管 ScaleTransform 有效,但我的应用程序允许人们添加更多形状并再次减去或添加,并且 scaletransform 会将所有内容都扔掉。让我试试你的第一个。
    • 这会产生相同的结果,即由已“排除”的矩形和椭圆组成的路径仅用一条线绘制。我将添加一些图像来显示差异。
    • 因为每个路径图仍然必须有一个多边形。你不能只用一个多边形来绘制一组不相连的图形。请重新阅读我对您上一个问题的回答的 cmets。
    • 请注意,ScaleTransform 应用于 Path.Data 的克隆,而不是原始几何体。
    • 我的应用程序允许多人通过网络同时在自己的画布上绘图。当具有 1920x1080 的人创建组合几何形状时,我需要考虑屏幕分辨率,并且它需要在远程 PC 上重新创建并缩放到他们的分辨率。 scaletransform 适用于第一次显示,但之后分辨率比例就出来了。即:如果一些减去或添加另一个形状到关节路径。
    【解决方案2】:

    通过坚持找到答案。

    获取 flattenedpathgeometry 的每个点并为每个点添加比例并使用新点重新创建相同的 flattenedpathgeometry 的代码。希望它可以帮助某人。并感谢克莱门斯。感谢您的努力。

    path.Data = Geometry.Parse(CurrentObject.Geometry1);
    PathGeometry g = path.Data.GetFlattenedPathGeometry();
    
    PathGeometry g = path.Data.GetFlattenedPathGeometry();
    
    foreach (var f in g.Figures)
    {
    Point pt1 = f.StartPoint;
    pt1.X = pt1.X * ScaleX;
    pt1.Y = pt1.Y * ScaleY;
    strGeom += "M" + pt1.ToString();
        foreach (var s in f.Segments)
        if (s is PolyLineSegment)
        {
            count = 0;
            foreach (var pt in ((PolyLineSegment)s).Points)
        {
            int scount = ((PolyLineSegment)s).Points.Count;
            if (count == 0)
            {
                Point pts = new Point(pt.X * ScaleX, pt.Y * ScaleY);
                strGeom += "L" + pts.ToString();
            }
            else if (count < scount)
            {
                Point pts = new Point(pt.X * ScaleX, pt.Y * ScaleY);
                strGeom += " " + pts.ToString();
            }
            else if (count == scount)
            {
                Point pts = new Point(pt.X * ScaleX, pt.Y * ScaleY);
                strGeom += " " + pts.ToString() + "Z";
            }
            count++;
        }
        }
    }
    path.Data = Geometry.Parse(strGeom);
    

    这是从远程会话发送的路径图像:1366x768 缩放为 1920x1080

    【讨论】:

    • 这无疑是将几何与不同比例因子相结合的最复杂和低效的方法。请参阅我的答案中的编辑,了解如何更优雅地完成此操作。
    • 我在您的原始答案中添加了评论。该应用程序使用“Xor”、“Exclude”和“Union”,当有多种模式时,无法找出原始路径是由什么组成的。获得点和缩放它们的最佳方法似乎是从有效但由于屏幕分辨率不同而大小不同的扁平几何体。这是一个非常复杂的协作应用程序,因此在几十万行中添加几行似乎没问题。我毫不怀疑有更好的方法,但我还没有找到它,这很有效。我整天都在努力。干杯。
    猜你喜欢
    • 1970-01-01
    • 2014-11-16
    • 1970-01-01
    • 2020-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    相关资源
    最近更新 更多