【问题标题】:Simple MouseMove handling简单的 MouseMove 处理
【发布时间】:2012-10-11 09:59:22
【问题描述】:

我尝试编写一个简单的图形编辑器。我有下一个问题,当我使用SolidBrush() 绘制一些曲线时,我得到了中断的曲线(看图片)。我需要获得不间断的曲线。我尝试为此使用鼠标捕获,但它不起作用(结果相同)。我该如何解决?查看以下 MouseMove 事件处理程序的代码:

void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMouseDown)
            {
                pictureBox1.Capture = true; // I try to capture mouse here
                Graphics g = Graphics.FromHwnd(this.pictureBox1.Handle);
                g.FillRectangle(new SolidBrush(Color.Black), e.X, e.Y, 1, 1);
            }
        }

【问题讨论】:

    标签: c# winforms gdi+ gdi


    【解决方案1】:

    这取决于鼠标移动的速度,有时 MouseMove 事件会更频繁地触发,有时则不会。我认为这还取决于您的机器在该特定时刻加载了多少。如果你在两点之间画线,它们不会是弯曲的,而是直线的。相反,您应该查看BeziersSplines。这样,您将获得基于几个点的曲线。

    但是你可以用你的代码做点什么。每当您最后一次 mousedown 和当前 mousedown 事件之间的距离大于阈值时(您可以凭经验获得),您可以向曲线添加新点。 下面是添加一个点的示例代码:

     public bool isMouseDown { get; set; }
            Point lastPoint = Point.Empty;
            public double treshold { get; set; }
            private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
            {
                if (isMouseDown)
                {
                    pictureBox1.Capture = true; // I try to capture mouse here
                    Graphics g = Graphics.FromHwnd(this.pictureBox1.Handle);
                    if (Math.Sqrt(Math.Pow(e.X - lastPoint.X, 2) + Math.Pow(e.Y - lastPoint.Y, 2)) > treshold)
                    {
                        g.FillRectangle(new SolidBrush(Color.Black), (e.X + lastPoint.X)/2, (e.Y + lastPoint.Y)/2, 1, 1);
    
                    }
    
                    g.FillRectangle(new SolidBrush(Color.Black), e.X, e.Y, 1, 1);
                    lastPoint = new Point(e.X, e.Y);
                }
            }
    
            private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
            {
                isMouseDown = true;
                lastPoint = new Point(e.X, e.Y);
            }
    
            private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
            {
                isMouseDown = false;
            }
    

    【讨论】:

    • 我知道我可以使用贝塞尔等多项式算法来做到这一点,但我不能做到这一点吗?不可能吗?
    • @Vsevywniy 根据我的经验,您无法影响将引发多少 mousemove 事件的速率。也没有触发鼠标移动的最小距离。因此你会得到中断的曲线。
    • 当我在标准窗口中使用铅笔工具绘制图形编辑器时,我得到了不间断的曲线。是不是说它是用贝塞尔等多项式算法形成的?
    • @Vsevywniy 检查编辑后的答案。我认为他们只是使用了一些技巧,例如我在答案中编辑的技巧,因此用户不会注意到差异。
    【解决方案2】:

    不要画点,而是记住你最后的鼠标位置,并从它画线到当前的鼠标位置。

    【讨论】:

    • 不,因为鼠标移动不是逐个像素的。
    【解决方案3】:

    除了鼠标移动的问题,这里还有另一个更严重的问题。

    使用Graphics g = Graphics.FromHwnd(this.pictureBox1.Handle) 并直接在图形表面上绘制将是暂时的,因为像素会消失。

    鲍勃·鲍威尔对此也有很好的回答。

    查看他的第 1 个最常见的 GDI+ 问题:https://web.archive.org/web/20131226033137/http://bobpowell.net/picturebox.aspx

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-21
      • 1970-01-01
      • 2013-07-30
      • 2016-03-20
      • 2014-10-06
      • 2018-06-29
      • 2013-01-10
      相关资源
      最近更新 更多