WPF : GeneralTransform을 지오메트리 데이터에 적용하고 새 지오메트리를 반환하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/249971

문제

일부 형상 데이터와 변환이 있으면 형태 변환을 어떻게 변환 할 수 있도록 형태 변환을 어떻게 적용 할 수 있습니까?

예 : 경로가있는 경로 객체가 있습니다 .Data는 PathGeometry 객체로 설정되어 있습니다. 포인트 PathGeometry 객체의 제자리에 변환을 사용하고 렌더링 시간에 사용될 PathGeometry에 변환을 적용하지 않습니다.

추신 Transform 클래스에 메소드가 있다는 것을 알고 있습니다. Point Transform.Transform(Point p) 그것은 점을 변형시키는 데 사용될 수 있지만 ... 한 번에 임의의 형상을 변형시키는 방법이 있습니까?

편집 : 현재 발견 된 A에 대해서는 Repply를 참조하십시오 해결책

도움이 되었습니까?

해결책

geometry.combine을 사용할 수 있습니다. 결합 중에 변환을 적용합니다. 한 가지 캐치는 결합에 지오메트리에 영역이있는 경우에만 작동하므로 단일 라인이 작동하지 않습니다.

다음은 저를 위해 일한 샘플입니다.

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

다른 팁

나는 임의의 트랜 포름을 경로 형상에 적용 할 수있는 솔루션을 찾았습니다. 토드 화이트답변 :

기본적으로 geometry.combine은 원하는 지오메트리를 Geometry와 결합하는 데 사용되며 Union을 사용하여 원하는 변환이 제공됩니다. 결과 형상은 주어진 변환으로 변환됩니다.

PathGeometry geometryTransformed = Geometry.Combine(Geometry.Empty, geometry, GeometryCombineMode.Union, transform);

이것은 내가 발견 한 모든 그림 정보를 손상되지 않은 채로 변환 된 형상을 얻기 위해 할 수있는 것입니다.

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

수락 된 답변은 원래의 것과 다른 형식으로 지오메트리를 반환하고 있었기 때문에 사용하지 않았으므로 다음을 사용했습니다.

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

Geometry.combine을 기반으로 한 빠른 솔루션은 단일 라인 레벨로 만들어진 경로의 경우 작동하지 않습니다. 그래서 나는 이와 같은 어려운 방법을 해결했습니다 (그러나 나는 또한 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;
}
}

불행히도, 나는 당신이 요구하는 일을하는 방법이나 속성이 있다고 생각하지 않습니다. 적어도 나는 하나를 찾을 수 없습니다. (좋은 질문!)

당신이 수동으로해야 할 것 같습니다 (당신이 스스로 제안하는 것처럼) ... 전화입니다. Point Transform.Transform (Point P) PathGeometry의 모든 지점에 대해 ... 프로세스에서 새로운 PathGeometry를 생성합니다.

아마도 당신이 원하는 대답이 아닐 것입니다. (rueful mate)

나는 같은 문제를 겪었고 선이 필요했습니다 (면적이있는 기하학뿐만 아니라).

나는 PathGeometry 만 사용하고 있으므로 이것이 당신이 찾고있는 일반적인 솔루션이 아닐 수도 있지만 이것은 나에게 효과적입니다.

pathgeometry.Transform = transform;
PathGeometry transformed =  PathGeometry.CreateFromGeometry(pathgeometry);

고려해야 할 두 가지가 있습니다.

  1. 형상이 냉동실에서 상속되면, 얼어 붙은 경우 지오메트리 개체를 현장에서 수정할 수 없습니다.
  2. PathGeometry의 그림 및 세그먼트 목록을 스캔하고 모든 지점을 변환 할 수 있지만 ArcSegment와 같은 일부 유형에는 크기 및 각도가 포함되어 있으므로 변환 할 수 없습니다.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top