14

有一些几何数据和变换如何将变换应用于几何以得到一个新的几何与它的数据转换?

例如:我有一个 Path 对象,它的 Path.Data 设置为 PathGeometry 对象,我想使用变换来变换PathGeometry 对象,而不是对将在渲染时使用的 PathGeometry 应用变换.

PS我知道Transform类有一个Point Transform.Transform(Point p)可以用来变换Point的方法但是......有没有办法一次变换任意几何?

编辑:查看我的回复以获取当前找到的解决方案

4

8 回答 8

15

感谢Todd White的回答,我找到了一个可以将任意变换应用于路径几何的解决方案:

基本上 Geometry.Combine 用于使用 Union 将所需的几何图形与 Geometry.Empty 组合,并给出所需的变换。生成的几何图形使用给定的变换进行变换。

PathGeometry geometryTransformed = Geometry.Combine(Geometry.Empty, geometry, GeometryCombineMode.Union, transform);
于 2008-10-30T16:54:02.867 回答
11

您可以尝试使用 Geometry.Combine。它在合并期间应用变换。一个问题是,Combine 仅在您的 Geometry 具有区域时才有效,因此单行将不起作用。

这是一个对我有用的示例。

PathGeometry geometry = new PathGeometry();
geometry.Figures.Add(new PathFigure(new Point(10, 10), new PathSegment[] { new LineSegment(new Point(10, 20), true), new LineSegment(new Point(20, 20), true) }, true));
ScaleTransform transform = new ScaleTransform(2, 2);
PathGeometry geometryTransformed = Geometry.Combine(geometry, geometry, GeometryCombineMode.Intersect, transform);
于 2008-10-30T15:25:21.187 回答
8

这就是我发现你可以做的就是得到一个完整的所有图形信息的转换几何:

var geometry = new PathGeometry();
geometry.Figures.Add(new PathFigure(new Point(10, 10), new PathSegment[] { new LineSegment(new Point(10, 20), true), new LineSegment(new Point(20, 20), true) }, true));
geometry.Transform = new ScaleTransform(2, 2);

var transformedGeometry = new PathGeometry ();
// this copies the transformed figures one by one into the new geometry
transformedGeometry.AddGeometry (geometry); 
于 2012-12-19T19:48:47.013 回答
3

我没有使用接受的答案,因为它返回的几何格式与原始格式不同,所以我使用了这个:

Geometry inputGeometry = new PathGeometry();
var inputGeometryClone = inputGeometry.Clone(); // we need a clone since in order to
                                                // apply a Transform and geometry might be readonly
inputGeometryClone.Transform = new TranslateTransform(); // applying some transform to it
var result = inputGeometryClone.GetFlattenedPathGeometry();
于 2011-09-22T12:52:07.367 回答
2

基于 Geometry.Combine 的快速解决方案均不适用于由单个 LineElement 构成的路径。所以我用艰难的方式解决了这个问题,就像这样(但我也仅限于 PathGeometry):

public static class GeometryHelper
{
public static PointCollection TransformPoints(PointCollection pc, Transform t)
{
  PointCollection tp = new PointCollection(pc.Count);
  foreach (Point p in pc)
    tp.Add(t.Transform(p));
  return tp;
}
public static PathGeometry TransformedGeometry(PathGeometry g, Transform t)
{
  Matrix m = t.Value;
  double scaleX = Math.Sqrt(m.M11 * m.M11 + m.M21 * m.M21);
  double scaleY = (m.M11 * m.M22 - m.M12 * m.M21) / scaleX;
  PathGeometry ng = g.Clone();
  foreach (PathFigure f in ng.Figures)
  {
    f.StartPoint = t.Transform(f.StartPoint);
    foreach (PathSegment s in f.Segments)
    {
      if (s is LineSegment)
        (s as LineSegment).Point = t.Transform((s as LineSegment).Point);
      else if (s is PolyLineSegment)
        (s as PolyLineSegment).Points = TransformPoints((s as PolyLineSegment).Points, t);
      else if (s is BezierSegment)
      {
        (s as BezierSegment).Point1 = t.Transform((s as BezierSegment).Point1);
        (s as BezierSegment).Point2 = t.Transform((s as BezierSegment).Point2);
        (s as BezierSegment).Point3 = t.Transform((s as BezierSegment).Point3);
      }
      else if (s is PolyBezierSegment)
        (s as PolyBezierSegment).Points = TransformPoints((s as PolyBezierSegment).Points, t);
      else if (s is QuadraticBezierSegment)
      {
        (s as QuadraticBezierSegment).Point1 = t.Transform((s as QuadraticBezierSegment).Point1);
        (s as QuadraticBezierSegment).Point2 = t.Transform((s as QuadraticBezierSegment).Point2);
      }
      else if (s is PolyQuadraticBezierSegment)
        (s as PolyQuadraticBezierSegment).Points = TransformPoints((s as PolyQuadraticBezierSegment).Points, t);
      else if (s is ArcSegment)
      {
        ArcSegment a = s as ArcSegment;
        a.Point = t.Transform(a.Point);
        a.Size = new Size(a.Size.Width * scaleX, a.Size.Height * scaleY); // NEVER TRIED
      }
    }
  }
  return ng;
}
}
于 2014-12-16T15:19:38.507 回答
0

不幸的是,我认为没有方法或属性可以满足您的要求。至少,我一个也找不到。(好问题!)

似乎您必须手动执行此操作(正如您自己建议的那样)......即为 PathGeometry 中的每个点调用Point Transform.Transform(Point p) ......在此过程中创建一个新的 PathGeometry 。

可能不是你想要的答案。(悔恨的笑容)

于 2008-10-30T13:59:17.117 回答
0

我遇到了同样的问题并且也需要线条(不仅是具有面积的几何图形)。

我只使用 PathGeometry,所以这可能不是您正在寻找的通用解决方案,但这对我有用:

pathgeometry.Transform = transform;
PathGeometry transformed =  PathGeometry.CreateFromGeometry(pathgeometry);
于 2009-10-01T15:05:57.027 回答
-1

您必须考虑两件事:

  1. 几何体继承自 Freezable,如果几何体对象被冻结,则无法就地修改它。
  2. 您可以扫描图形和线段的 PathGeometry 列表并转换其中的所有点,但某些类型,如 ArcSegment 包括大小和角度,您无法转换它们。
于 2008-10-30T12:38:59.510 回答