如何在 GDI 中移动缩放线+

发布于 2024-12-21 01:40:33 字数 2859 浏览 5 评论 0原文

我有一个图片盒。 在图片框中,我使用以下方法绘制线条:

gfx.DrawLine(nPen, line.xBegin, line.yBegin, line.xEnd, line.yEnd);

line 是一个包含以下内容的对象:行的起始值和结束值。

我在那个图片框上画了 10 条线。 我的 mouse_Wheel 侦听器包含代码:

gfx.TranslateTransform((panelpreview.Width) / 2, (panelpreview.Height) / 2);
gfx.ScaleTransform(imageScale, imageScale);
gfx.TranslateTransform(-(panelpreview.Width) / 2, -(panelpreview.Height) / 2);

目前我正在尝试通过以下方式移动线条:

    private void panelPreview_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            checkLinesIntersection(e.Location); //checks if e.Location intersects with the line
            panelPreview.MouseUp += new MouseEventHandler(panelPreview_MouseUpLine);
            panelPreview.MouseMove += new MouseEventHandler(panelPreview_MouseMoveLine);
        }
    }

    void panelPreview_MouseMoveLine(object sender, MouseEventArgs e)
    {
        if (_Leading.movable)
            newFont.Leading = e.Y - (_base.yBegin + newFont._descenderHeight);

        if (_xHeight.movable)
            if (_base.yBegin - e.Y >= 0)
                newFont.xHeight = _base.yBegin - e.Y;

        if (_capHeight.movable)
            if (_base.yBegin - e.Y >= 0)
                newFont.capHeight = _base.yBegin - e.Y;

        if (_ascenderHeight.movable)
            if (_base.yBegin - e.Y >= 0)
                newFont.ascenderHeight = _base.yBegin - e.Y;

        if (_descenderHeight.movable)
            if (e.Y - _base.yBegin >= 0)
                newFont.descenderHeight = e.Y - _base.yBegin;

        UpdatePreviewWindow();
    }

    void panelPreview_MouseUpLine(object sender, MouseEventArgs e)
    {
        panelPreview.MouseMove -= new MouseEventHandler(panelPreview_MouseMoveLine);
        panelPreview.MouseUp -= new MouseEventHandler(panelPreview_MouseUpLine);
    }

问题是,在放大后,即使在视觉上我确实按下了线条,它也没有按照应有的方式做出反应。

    public void checkLinesIntersection(Point mouseLocation)
    {
        lineIntersects(_Leading, mouseLocation);
        lineIntersects(_xHeight, mouseLocation);
    }

    private void lineIntersects(nLine line, Point mouseLocation)
    {
        if (mouseLocation.X >= line.xBegin && mouseLocation.X <= line.xEnd)
            if (mouseLocation.Y >= line.yBegin || mouseLocation.Y + 2 >= line.yBegin)
                if (mouseLocation.Y <= line.yEnd || mouseLocation.Y - 2 <= line.yEnd)
                    switch (line.sName)
                    {
                        case "xHeight":
                            newFont.selectedLine = nFont.Lines._xHeight;
                            break;
                        default:
                            break;
                    }
    }

I have a picture box.
In picture box I draw lines using:

gfx.DrawLine(nPen, line.xBegin, line.yBegin, line.xEnd, line.yEnd);

line is an object containing lines beginning and end values.

I draw 10x lines on that picture box.
My mouse_Wheel listener contains code:

gfx.TranslateTransform((panelpreview.Width) / 2, (panelpreview.Height) / 2);
gfx.ScaleTransform(imageScale, imageScale);
gfx.TranslateTransform(-(panelpreview.Width) / 2, -(panelpreview.Height) / 2);

currently I am trying to move lines by:

    private void panelPreview_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            checkLinesIntersection(e.Location); //checks if e.Location intersects with the line
            panelPreview.MouseUp += new MouseEventHandler(panelPreview_MouseUpLine);
            panelPreview.MouseMove += new MouseEventHandler(panelPreview_MouseMoveLine);
        }
    }

    void panelPreview_MouseMoveLine(object sender, MouseEventArgs e)
    {
        if (_Leading.movable)
            newFont.Leading = e.Y - (_base.yBegin + newFont._descenderHeight);

        if (_xHeight.movable)
            if (_base.yBegin - e.Y >= 0)
                newFont.xHeight = _base.yBegin - e.Y;

        if (_capHeight.movable)
            if (_base.yBegin - e.Y >= 0)
                newFont.capHeight = _base.yBegin - e.Y;

        if (_ascenderHeight.movable)
            if (_base.yBegin - e.Y >= 0)
                newFont.ascenderHeight = _base.yBegin - e.Y;

        if (_descenderHeight.movable)
            if (e.Y - _base.yBegin >= 0)
                newFont.descenderHeight = e.Y - _base.yBegin;

        UpdatePreviewWindow();
    }

    void panelPreview_MouseUpLine(object sender, MouseEventArgs e)
    {
        panelPreview.MouseMove -= new MouseEventHandler(panelPreview_MouseMoveLine);
        panelPreview.MouseUp -= new MouseEventHandler(panelPreview_MouseUpLine);
    }

The problem is that after zooming in even though visually I do press on the line its not reacting the way it should.

    public void checkLinesIntersection(Point mouseLocation)
    {
        lineIntersects(_Leading, mouseLocation);
        lineIntersects(_xHeight, mouseLocation);
    }

    private void lineIntersects(nLine line, Point mouseLocation)
    {
        if (mouseLocation.X >= line.xBegin && mouseLocation.X <= line.xEnd)
            if (mouseLocation.Y >= line.yBegin || mouseLocation.Y + 2 >= line.yBegin)
                if (mouseLocation.Y <= line.yEnd || mouseLocation.Y - 2 <= line.yEnd)
                    switch (line.sName)
                    {
                        case "xHeight":
                            newFont.selectedLine = nFont.Lines._xHeight;
                            break;
                        default:
                            break;
                    }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

韵柒 2024-12-28 01:40:33

所以!在使用这个工具一段时间后,我改变了方法并使用 XNA 来处理图形(绘制、缩放、移动绘制对象)。
对我帮助很大的是在 XNA 中使用 CameraMatrix 进行转换。
反正!我不会发布我的 XNA 解决方案来处理这个问题,但是通过使用 XNA,我找到了在 WinForms 中处理它的方法。

float Zoom = 1f;
Microsoft.Xna.Framework.Rectangle mouseRect;
Matrix inverse;

void TAB_PICTURE_BOX_MouseWheel(object sender, MouseEventArgs e)
    {
        try
        {
            if (e.Delta > 0)
            {
                Zoom+= .1f;
            }
            if (e.Delta < 0)
            {
                Zoom -= .1f;
            }

            gfx.ResetTransform();
            gfx.TranslateTransform((Width + img.Width) / 2, (Height - img.Height) / 2);
            gfx.ScaleTransform(Zoom, Zoom);
            gfx.TranslateTransform(-(Width + img.Width) / 2, -(Height - img.Height) / 2);      
                getInversePosition(e);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

最后一点 getInversePosition(e); 方法:

 private void getInversePosition(MouseEventArgs e)
    {
        Matrix matrix = Matrix.CreateTranslation(new Vector3(-(Width + img.Width) / 2, -(Height - img.Height) / 2, 0)) *
                  Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
                  Matrix.CreateTranslation(new Vector3((Width + img.Width) / 2, (Height - img.Height) / 2, 0));

        inverse = Matrix.Invert(matrix);
        Vector2 mousePosition = Vector2.Transform(new Vector2(e.X, e.Y), inverse);
        mouseRect = new Microsoft.Xna.Framework.Rectangle((int)mousePosition.X, (int)mousePosition.Y, 1, 1);
    }

我确信有一种方法可以在没有 XNA 参与的情况下处理它,但在我的场景中 XNA 成功了。

So! After working for a while on this tool I changed the approach and used XNA to handle graphics (drawing, zooming, moving draw objects).
What helped me a lot was usage of Camera in XNA and Matrix to transform.
ANYWAY! I am not gonna post my solution for XNA to handle this problem BUT by using XNA I found the approach to handle it in WinForms.

float Zoom = 1f;
Microsoft.Xna.Framework.Rectangle mouseRect;
Matrix inverse;

void TAB_PICTURE_BOX_MouseWheel(object sender, MouseEventArgs e)
    {
        try
        {
            if (e.Delta > 0)
            {
                Zoom+= .1f;
            }
            if (e.Delta < 0)
            {
                Zoom -= .1f;
            }

            gfx.ResetTransform();
            gfx.TranslateTransform((Width + img.Width) / 2, (Height - img.Height) / 2);
            gfx.ScaleTransform(Zoom, Zoom);
            gfx.TranslateTransform(-(Width + img.Width) / 2, -(Height - img.Height) / 2);      
                getInversePosition(e);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

And the final touch getInversePosition(e); method:

 private void getInversePosition(MouseEventArgs e)
    {
        Matrix matrix = Matrix.CreateTranslation(new Vector3(-(Width + img.Width) / 2, -(Height - img.Height) / 2, 0)) *
                  Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
                  Matrix.CreateTranslation(new Vector3((Width + img.Width) / 2, (Height - img.Height) / 2, 0));

        inverse = Matrix.Invert(matrix);
        Vector2 mousePosition = Vector2.Transform(new Vector2(e.X, e.Y), inverse);
        mouseRect = new Microsoft.Xna.Framework.Rectangle((int)mousePosition.X, (int)mousePosition.Y, 1, 1);
    }

I am sure that there is a way to handle it without XNA involvement BUT in my scenario XNA made the work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文