.NET Drawing2D中缺少原生功能来翻转Y轴的问题是众所周知的。可悲的是,机械,建筑和其他工程师从未开始以“上下颠倒”的方式绘制图纸...因为我想对我的旧代码进行认真的重构,所以我问到最佳出路 >这个问题。我不想“发明轮子”,如果以前已经做过。
论坛中的问题通常集中在一个非常特殊的问题上,但是麻烦的是,我曾经阅读和实施的所有建议的解决方法在某个阶段都有严重的缺点。
为避免常见的经过测试的建议,以下是我所知道的解决方法:
1)在每次绘制时重新计算Y坐标
Public Function GetYinCCS (Y as Single, ContainerHeight as Int32) As Single
Dim RetVal as Single
RetVal = ContainerHeight - Y
Return RetVal
End Funciton
...
Dim MyCartesianRectangle as New RectangleF(120,GetYinCCS(75),400,200)
g.DrawRectangle(Pens.Black, MyCartesianRectangle)
这看起来不错,这些年来我经常使用它。但这很疯狂,即使您自己制作了一个绘图子图层,例如:
Public Sub DrawRec (RPen as Pen, Rec as RectangleF, g as Graphics, bm as Bitmap)
g.DrawRectangle(RPen, Rectangle.Round(New Rectangle(Rec.X, bm.Height - Rec.Y, Rec.Width, Rec.Height)))
End Sub
您必须在所有位置执行此操作-在静态绘画中,在_Paint事件中,鼠标事件中的鼠标位置等等。等等。这是工作的全部 并令人恐惧...在翻转的环境中使用转换函数也是一个真正的“乐趣”。
2)缩放轴
那为什么不简单地翻转Y轴呢?
g.TranslateTransform(0, bm.Height) ' move graphics to the new start of Coordinate System
g.ScaleTransform(1, -1) ' flip the graphics vertically (along horizontal axis)
太好了!不,哎呀,字符串现在是上下颠倒了……但这可以通过在您的个人DrawStr方法中进行两次转换来解决:
g.ScaleTransform(1, -1) ' flip the flipped bitmap vertically
g.TranslateTransform(0, -bm.Height)
g.DrawString("My string", Me.Font, Brushes.Navy, Pt)
g.TranslateTransform(0, bm.Height)
g.ScaleTransform(1, -1) ' flip the flipped-flipped bitmap vertically - back
没关系。但是,尝试以垂直的自下而上的方向或以一定的角度画线时,很可能会把头发从头上拉下来。 为什么不使用g.ResetTransform()?因为我做不到,至少在当前设置中。我会松开Y型翻盖,如果我使用了转换功能进行平移和缩放,我也会松开它。
我们不要忘记,您的鼠标也使用不同的Y语言,并且不要忘记_Paint事件电子图形也必须进行ScaleTransformed ...
也许编写一个 Reset 函数,该函数将执行ResetTransform()然后执行Y-Flip然后缩放和平移变换(以获取绘图空间的“开始”设置)可能会有所帮助。这必须在每个函数本身都需要执行转换函数(例如,成角度的DrawString)之后完成。
3) LOW LEVEL GDI Y-SWAP
我在某处读到了一种关于对控件的Y坐标进行低级翻转的方法,我尝试对其进行测试,但未成功。我现在找不到。无论如何,都有关于严重退步的警告。 编辑:这是一个提及此方法的地方: SetViewportOrgEx()
所以我想知道,最好的方法是什么,如何使事情保持整洁?也许一些复杂的矩阵运算?
为清楚起见,我说的是.NET环境中的解决方案。