14

いくつかの Geometry データと Transform がある場合、どのように変換を Geometry に適用して、データが変換された新しい Geometry を取得できますか?

例: Path.Data が PathGeometry オブジェクトに設定されている Path オブジェクトがあり、変換を使用して PathGeometry オブジェクトのポイントを所定の位置に変換し、レンダリング時に使用される PathGeometry に変換を適用したくありません。 .

PS Transform クラスには Point を変換するために使用できるメソッドがあることは知ってPoint Transform.Transform(Point p)いますが、任意のジオメトリを一度に変換する方法はありますか?

編集:現在見つかった解決策については、返信を参照してください

4

8 に答える 8

15

Todd Whiteの回答のおかげで、任意の変換をパス ジオメトリに適用できるソリューションを見つけました。

基本的に Geometry.Combine は、目的のジオメトリを Geometry.Empty に Union を使用して結合するために使用され、目的の変換が与えられます。結果のジオメトリは、指定された変換で変換されます。

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

Geometry.Combine を試すことができます。結合中に変換を適用します。1 つのキャッチは、ジオメトリに領域がある場合にのみ結合が機能するため、単一の線が機能しないことです。

これが私のために働いたサンプルです。

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

考慮しなければならないことが 2 つあります。

  1. ジオメトリは Freezable から継承されます。ジオメトリ オブジェクトが固定されている場合、ジオメトリ オブジェクトをその場で変更することはできません。
  2. 図形とセグメントの PathGeometry リストをスキャンして、それらのすべてのポイントを変換できますが、ArcSegment にサイズと角度が含まれているなど、一部のタイプは変換できません。
于 2008-10-30T12:38:59.510 に答える