WPF中如何添加不随缩放变大的点几何图形?
问题描述
我正在创建由线条和椭圆构成的几何图形,现在想为该几何图形添加点,目前通过创建小半径椭圆来实现此需求。但问题是我会对该几何图形应用变换,当执行平移和缩放操作时,这些点会变得很大。请问如何添加点才能让它们在缩放时不会变大?
现有代码
public static Path PointsGeometry(List<Point> Locations, Transform transform) { GeometryGroup geometries = new GeometryGroup(); foreach (Point Location in Locations) { geometries.Children.Add(new EllipseGeometry { Center = Location, RadiusX = .5, RadiusY = .5, } ); } geometries.Transform = transform; Path path = new Path { Fill = Brushes.WhiteSmoke, Data = geometries, }; return path; }
解决方案
核心思路是让点的大小不受缩放变换的影响,下面提供几种可行的实现方式:
方式一:用Canvas放置固定尺寸的Ellipse作为点
把主几何图形和点都放在同一个Canvas中,主图形应用完整的平移+缩放变换,而点仅应用平移变换,保持自身尺寸固定:
public static void AddFixedSizePoints(Canvas canvas, List<Point> locations, Transform mainTransform) { // 从主变换中提取平移分量 TranslateTransform translate = null; if (mainTransform is TransformGroup group) { translate = group.Children.OfType<TranslateTransform>().FirstOrDefault(); } else if (mainTransform is TranslateTransform tt) { translate = tt; } foreach (Point loc in locations) { Ellipse point = new Ellipse { Width = 2, Height = 2, Fill = Brushes.WhiteSmoke, }; // 定位点的位置,抵消自身尺寸的偏移 double offset = 1; Canvas.SetLeft(point, loc.X - offset); Canvas.SetTop(point, loc.Y - offset); // 应用平移变换(如果主变换包含平移) if (translate != null) { point.RenderTransform = translate; } canvas.Children.Add(point); } }
这种方式下,点的尺寸固定,不会随主图形的缩放而变大。
方式二:修改原有代码,抵消缩放对几何图形的影响
如果坚持用Path绘制点,可以对几何图形应用逆缩放变换,抵消主变换中的缩放效果:
public static Path PointsGeometry(List<Point> Locations, Transform transform) { GeometryGroup geometries = new GeometryGroup(); foreach (Point Location in Locations) { geometries.Children.Add(new EllipseGeometry { Center = Location, RadiusX = .5, RadiusY = .5, } ); } // 提取主变换的矩阵,生成逆缩放矩阵(保留平移) Matrix matrix = transform.Value; Matrix inverseScaleMatrix = new Matrix( 1 / matrix.M11, 0, 0, 1 / matrix.M22, matrix.OffsetX, matrix.OffsetY ); geometries.Transform = new MatrixTransform(inverseScaleMatrix); Path path = new Path { Fill = Brushes.WhiteSmoke, Data = geometries, }; return path; }
通过将主变换的缩放分量取倒数,让点的几何图形在缩放时反向缩放,最终呈现的大小保持不变。
方式三:在自定义控件的OnRender中直接绘制点
如果是自定义控件,可重写OnRender方法,根据当前缩放比例动态调整点的绘制大小:
private List<Point> _points = new List<Point>(); protected override void OnRender(DrawingContext dc) { base.OnRender(dc); // 获取当前控件的缩放变换比例 Matrix transform = this.RenderTransform.Value; double scale = Math.Max(Math.Abs(transform.M11), Math.Abs(transform.M22)); // 确保点的实际显示大小固定为2px double pointRadius = scale > 0 ? 1 / scale : 1; foreach (Point loc in _points) { dc.DrawEllipse(Brushes.WhiteSmoke, null, loc, pointRadius, pointRadius); } }
这种方式直接根据当前缩放比例动态调整绘制参数,保证点的显示大小始终一致。
内容的提问来源于stack exchange,提问作者Harxish
相关产品推荐
相关产品推荐

