flip coordinates when drawing to control

16

我正在一个控件上绘制图形,但是0,0位于控件的左上角。是否有一种方法可以翻转坐标轴使得0,0位于控件的左下角?


你正在使用WinForms还是WPF?你可能想要更新您问题的标签。 - Drew Noakes
5个回答

23

如果您正在使用WinForms,则可以使用Graphics.ScaleTransform翻转Y轴:

private void ScaleTransformFloat(PaintEventArgs e)
{
    // Begin graphics container
    GraphicsContainer containerState = e.Graphics.BeginContainer();

    // Flip the Y-Axis
    e.Graphics.ScaleTransform(1.0F, -1.0F);

    // Translate the drawing area accordingly
    e.Graphics.TranslateTransform(0.0F, -(float)Height);

    // Whatever you draw now (using this graphics context) will appear as
    // though (0,0) were at the bottom left corner
    e.Graphics.DrawRectangle(new Pen(Color.Blue, 3), 50, 0, 100, 40);

    // End graphics container
    e.Graphics.EndContainer(containerState);

    // Other drawing actions here...
}

只需在需要使用常规坐标系进行其他绘图时,才需要包含起始/结束容器调用。有关图形容器的更多信息,请参见MSDN上的相关内容

正如Tom在评论中提到的那样,此方法要求Height值可用且具有正确的值。如果尝试此操作但未看到任何绘制内容,请在调试器中确保该值正确。


谢谢Eric。我已经更新了我的答案,并包括使用图形容器来隔离这些变换与其他更改的信息。 - Drew Noakes
对我没用。我还不是WinForms专家。事实证明,“Height”与当前控件无关。我在我的panel.OnPaint中调用了它,但什么也没有画出来。提到你假设你正在绘制到表单本身上可能会为其他人节省一些时间,因为它本可以为我节省一些调试时间 ;) - Tom
@Tom,根据您的经验,我已经添加了澄清。谢谢。 - Drew Noakes
1
@DrewNoakes,这个解决方案不完整,因为DrawString生成的文本无效,例如被垂直翻转了。 - alehro
非常正确。如果您正在绘制文本,则无法使用此方法。 - Drew Noakes
哦,但它确实可以用于文本。它被垂直翻转了,这是它的设计目的。变换会影响所有东西,为什么要排除文本呢?你可以对将要绘制文本的区域应用二次变换(包装drawstring函数并使用measurestring确定受影响矩形部分的大小)。 - Cee McSharpface

3
这是一个简单的用户控件,演示了如何实现这一点:
public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);

        InitializeComponent();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.ScaleTransform(1.0F, -1.0F);
        e.Graphics.TranslateTransform(0.0F, -(float)Height);
        e.Graphics.DrawLine(Pens.Black, new Point(0, 0), new Point(Width, Height));

        base.OnPaint(e);
    }
}

1

不过,使用控件的 Size(或 Height)属性,可以轻松计算翻转坐标:只需绘制到 Height-y


0

简而言之不行,但如果我需要频繁地操作控件,我有一些帮助我的函数:

Point GraphFromRaster(Point point)  {...}
Point RasterFromGraph(Point point)  {...}

这样我可以将所有的转换都放在一个地方,不必担心像y - this.Height这样散落在代码中的事情。


0

我不知道有没有,但如果你使用 (x,Control.Height-y),你会得到相同的效果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接