路径的不变笔画粗细(与比例尺无关) [英] Invariant stroke thickness of Path regardless of the scale

查看:111
本文介绍了路径的不变笔画粗细(与比例尺无关)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用wpf开发类似于cad的应用程序,其中使用Path对象将图形放置在画布上. 我只是遇到一个小问题,每当我缩放/缩放画布时,画布中的所有元素都会被缩放,这是我想要的行为,但这也增加了Path的笔触粗细.

We are using wpf to develop a cad like application where drawings placed on the canvas using the Path object. I just ran into a slight issue that whenver i scale/zoom my canvas, all the elements in the canvas get scaled and this is the behaviour i wanted but this also increases the stroke thickness of the Path.

有没有办法增加/缩放/缩放对象,但仍然保持路径的笔触粗细.

Is there a way by which i increase/scale/zoom the objects but still i maintain the same stroke thickness of the path.

在这方面的任何帮助对我来说都是非常有用的.

Any help in this regard will be very useful for me.

推荐答案

更好的解决方案是使用一个或多个System.Windows.Media.Geometry对象存储路径,点等.

A better solution would be to use one or more System.Windows.Media.Geometry object to store your paths, points etc.

可以使用钢笔绘制此几何图形,因此缩放时确实可以更改笔触粗细,但是更灵活的是使用变换"属性.

This geometry can be drawn with a Pen, so you could indeed change the stroke thickness when you zoom, but more flexible is to use the Transform property.

使用变换,您可以缩放"几何图形表示的实际坐标,而不是可视化"-因此,绘制图形时,您无需摆弄渲染变换.

Using the transform, you can "zoom" the actual coordinates of the geometric representation and not the visualization - so when you draw it, you don't need to fiddle with render transforms.

要计算转换,我使用如下代码:

To compute the transform, I use the following code like:

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

其中fromPosition Rect应该包含未转换的边界,而toPosition Rect应该包含转换的边界.这也很容易将X和Y分别缩放,这通常是绘图所必需的.

where the fromPosition Rect should contain the untransformed bounds, and the toPosition Rect should contain the transformed bounds. This also trivially allows for scaling X and Y separately, which is often necessary for plotting.

计算几何边界很容易:

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

当然,如果需要,WPF可以告诉您需要渲染到哪些边界.放在一起,您可以做类似的事情

And of course WPF can tell you which bounds you need to render into, should that be necessary. Putting it together, you could do something like

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

使用此解决方案的优点是您无需弄乱RenderTransforms,可以自由使用独立剪切和/或缩放X和Y的变换,而不会在行中产生怪异的变形,并且您可以将Pen作为不透明的对象(即,更易于从UI进行自定义-如果您选择Pen width或其他,则无需进一步校正).

The advantage of using this solution is that you don't need to mess with RenderTransforms, you're free to use transforms that shear and/or scale X and Y independently without getting weird distortions in your lines, and you can treat the Pen as an opaque object (i.e. easier to customize from the UI - if you select Pen width or whatnot, no further correction is necessary).

这篇关于路径的不变笔画粗细(与比例尺无关)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆