【发布时间】:2020-07-16 11:13:17
【问题描述】:
是否可以使用不同的坐标系从现有的Graphics 创建另一个Graphics?例如,假设黑色矩形是我在OnPaint() 中得到的Graphics 对象的ClipRectangle。如果我只想在蓝色矩形内绘制,我将不得不不断计算偏移量。也就是说,要在蓝色矩形中的逻辑点 (0,0) 处绘制,我必须添加 x 和 y 偏移量。这使得绘图代码变得复杂。
有没有办法使用上面的Graphics 创建某种虚拟Graphics,但使用不同的坐标系?类似下面的东西
//not actual code
var virtualG = Graphics.FromExistingGraphics(e.Graphics, 200/*x1*/, 200/*y1*/, 1000/*x2*/, 600/*y2*/);
//Doing the same thing as e.Graphics.DrawLine(pen, 200, 200, 400, 400)
virtualG.DrawLine(pen, 0, 0, 200, 200);
//Draws nothing, NOT the same as e.Graphics.DrawLine(pen, 1100, 200, 1200, 400)
//, because its outside of the virtualG's bounds.
virtualG.DrawLine(pen, 900, 0, 1000, 200);
我想过用位图创建一个新的Graphics,在那里绘制,然后将位图从OnPaint复制到Graphics的指定位置,但这可能会很慢。
【问题讨论】:
-
Graphics.ScaleTransform、Matrix.Scale(以及所有相关的转换)、Rectangle.Inflate(更多...)
-
输出到
Graphics是输出的结束。但是您可以在此之前添加更多层,在不同的单元中操作,添加相机逻辑(在 2d 中也很有用),坐标转换,所需的抽象。因此,您可以拥有 2 个具有不同坐标系的平面,它们以某种方式定位在您的 2d/3d 世界中,并通过相机显示在屏幕上。 -
您还可以检查Graphics.TransformPoints 方法(工作,嗯,非常快)。所有转换(使用 Matrix 或提供的辅助方法)都可以应用于 Graphics 对象和 GraphicsPath 对象。结合起来,这些允许构建许多不同的工具。不提及可应用于钢笔和画笔的变换(请参阅有关此的 GraphicsPath,使用钢笔进行变换)
-
请注意:
Graphics对象不包含任何图形;它是一个工具,可让您绘制到相关位图上,包括控件的表面。系统需要在您无法控制的时候绘制所有控件的表面;因此,您要添加到这些表面的所有内容都必须从系统将调用的一个事件创建,即Paint事件。只有 非持久性 图形操作(例如显示动态橡皮筋矩形)可以使用从control.CreateGraphics()获得的Graphics对象。无需绘图即可测量... -
另外:您不能缓存 Graphics 对象,但您可以存储和恢复当前设置,包括缩放和平移..