Một giải pháp tốt hơn sẽ được sử dụng một hoặc đối tượng System.Windows.Media.Geometry hơn để lưu trữ đường dẫn của bạn, chỉ, vv
hình học này có thể được rút ra với Pen, vì vậy bạn thực sự có thể thay đổi đột quỵ độ dày khi bạn phóng to, nhưng linh hoạt hơn là sử dụng thuộc tính Biến đổi.
Sử dụng phép biến đổi, bạn có thể "thu phóng" tọa độ thực tế của đại diện hình học chứ không phải trực quan hóa - vì vậy khi bạn vẽ nó, bạn không cần phải fiddle với biến đổi kết xuất.
Để tính toán biến đổi, tôi sử dụng đoạn mã sau như:
public static Matrix TransformShape(Rect fromPosition, Rect toPosition, bool flipVertical) {
Matrix translateThenScale = Matrix.Identity;
//we first translate to origin since that's just easier
translateThenScale.Translate(-fromPosition.X, -fromPosition.Y);
//now we scale the graph to the appropriate dimensions
translateThenScale.Scale(toPosition.Width/fromPosition.Width, toPosition.Height/fromPosition.Height);
//then we flip the graph vertically around the viewport middle since in our graph positive is up, not down.
if (flipVertical)
translateThenScale.ScaleAt(1.0, -1.0, 0.0, toPosition.Height/2.0);
//now we push the graph to the right spot, which will usually simply be 0,0.
translateThenScale.Translate(toPosition.X, toPosition.Y);
return translateThenScale;
}
nơi fromPosition Rect nên chứa các giới hạn untransformed, và toPosition Rect nên chứa các giới hạn biến đổi. Điều này cũng trivially cho phép mở rộng X và Y một cách riêng biệt, mà thường là cần thiết cho âm mưu.
Thật dễ dàng để tính toán giới hạn của hình học của bạn:
Geometry graphGeom;
//[...]
//the bounds are modified by the transform, so we want no transform!
graphGeom.Transform = Transform.Identity;
Rect graphBounds = graphGeom.Bounds;
//then set the transform again
//or, if the transform is axis-aligned, the following _should_ work:
Rect graphBoundsAlt = graphGeom.Transform.Inverse.TransformBounds(graphGeom.Bounds);
Và tất nhiên WPF có thể cho bạn biết tiếp giáp bạn cần phải làm vào, mà cần thiết. Đưa nó lại với nhau, bạn có thể làm một cái gì đó giống như
public void RecomputeTransform(Rect targetRect, bool flipVertical) {
graphGeom.Transform = Transform.Identity;
Rect graphBounds = graphGeom.Bounds;
Matrix transMat = TransformShape(graphBounds,targetRect,flipVertical);
graphGeom.Transform = new MatrixTransform(transMat);
}
Ưu điểm của việc sử dụng giải pháp này là bạn không cần phải gây rối với RenderTransforms, bạn đang miễn phí để sử dụng biến mà cắt và/hoặc quy mô X và Y một cách độc lập mà không bị biến dạng lạ trong đường kẻ của bạn, và bạn có thể coi Bút là đối tượng mờ đục (tức là dễ dàng hơn để tùy chỉnh từ giao diện người dùng - nếu bạn chọn Chiều rộng bút hoặc không có gì, không cần sửa thêm nữa).
Điều này là tốt nếu quy mô x và y của bạn là đồng nhất, nhưng không hoạt động nếu tỷ lệ không giống nhau. – Klay