I can't say I entirely understand what you mean by "really change the pathpoints", but the Transform property on the Geometry will scale the Geometry before it is rendered and the Geometry will be rendered as though it were the scaled size (not a zoomed version of the original size). So, for example, the pen thickness will not increase (or decrease) like it would with a visual transform. I think this is what you are looking for.
So perhaps:
private void SetScaleAndTranslateTransform(object obj, double translateX, double translateY, double scaleWidth, double scaleHeight)
{
var geometryDrawing = obj as System.Windows.Media.GeometryDrawing;
if(geometryDrawing != null)
{
geometryDrawing.Transform = new MatrixTransform(scaleWidth, 0, 0, scaleHeight, translateX, translate);
return;
}
var drawingGroup = obj as System.Windows.Media.DrawingGroup;
if(drawingGroup == null) return;
foreach(object objChild in drawingGroup.Children)
SetScaleAndTranslateTransform(objChild, translateX, translateY, scaleWidth, scaleHeight);
}
Keep in mind you could also create the transform once and assign it to the appropriate Geometry instances and then simply modifying that transform will affect all of them without having to use recursion.
Updated:
Below is a quick example illustrating what I mean when I say to transform the points.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication3
{
public static class PathFigureExtensions
{
public static IEnumerable<Point> EnumeratePoints(this PathFigure figure)
{
yield return figure.StartPoint;
foreach (var segment in figure.Segments)
{
var lineSegment = segment as LineSegment;
if (lineSegment != null)
yield return lineSegment.Point;
else
{
var polyLineSegment = segment as PolyLineSegment;
if (polyLineSegment == null) continue;
foreach (var point in polyLineSegment.Points)
yield return point;
}
}
}
public static IEnumerable<Point> EnumeratePoints(this PathFigure figure, Transform t)
{
return EnumeratePoints(figure).Select(p => t.Transform(p));
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var figures = new[]{
new PathFigure(
new Point(0,0),
new[]{
new PolyLineSegment(
new []{
new Point(50,0),
new Point(50,50),
new Point(0,50),
}, true) as PathSegment
}, true)
};
UntransformedGeometry = new PathGeometry(figures);
UntransformedGeometryPoints = new PointCollection(UntransformedGeometry.Figures.First().EnumeratePoints());
TransformedGeometry = new PathGeometry(figures);
TransformedGeometry.Transform = new ScaleTransform(2, 2);
TransformedGeometryPoints = new PointCollection(UntransformedGeometry.Figures.First().EnumeratePoints(TransformedGeometry.Transform));
DataContext = this;
}
public PathGeometry UntransformedGeometry {get;private set;}
public PathGeometry TransformedGeometry { get; private set; }
public PointCollection UntransformedGeometryPoints { get; private set; }
public PointCollection TransformedGeometryPoints { get; private set; }
}
}
Here's the xaml I will use to demonstrate:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel Margin="5">
<Path Data="{Binding UntransformedGeometry}" Stroke="Red" Fill="Gray" StrokeThickness="1" UseLayoutRounding="true"/>
<Label Content="{Binding UntransformedGeometryPoints}"/>
<Path Data="{Binding TransformedGeometry}" Stroke="Blue" Fill="Gray" StrokeThickness="1" UseLayoutRounding="true"/>
<Label Content="{Binding TransformedGeometryPoints}"/>
</StackPanel>
</Window>
If you run this you will see a square with the dimensions you gave, a label with its points, another square twice as large as the original square, and another label showing the points transformed. The second square has the same apparent stroke thickness as the original square because it is logically transformed rather than visually.
I also demonstrate how the PathGeometry doesn't own the figures used to create it (I use the same PathFigure to create both geoetries); this is just one of many reasons why applying a transform to a PathFigure, or Geometry, etc. should not change the underlying values. I think this is also how a developer expect properties to behave; I
could see having a method that given a transform produced a new Geometry that had the points resulting from applying the transform (and the transform
not applied to it). You could exchange your GeometryDrawing's Geometry with that if you like (making it "effective").
This was a quick and dirty example. I could see you extending the various PathSegment types and PathFigure to expose this functionality on each and finally doing so to PathGeometry.