在C#中找到鼠标的速度

时间:2011-01-30 05:59:43

标签: c# winforms winapi mouseevent

如何在释放鼠标的 完全 时刻找到鼠标的瞬时垂直速度?我有用户拖动自定义控件,当他们发布时我需要知道这些信息,所以我可以使用速度的垂直分量继续他们拖动的对象...

因此,例如,如果他们以某个角度拖动,请使用trig来确定垂直速度,然后使用它。

我不能随着时间的推移做距离,因为鼠标可以以不规则的速度移动,这根本不代表正确的速度。

我原以为我可以使用MouseMove的触发器之间可能存在特定的间隔,但我不确定。

4 个答案:

答案 0 :(得分:8)

  

如何在鼠标释放的确切时刻找到鼠标的瞬时垂直速度?

你做不到。正如芝诺在几个世纪前所说的那样,速度只在一段时间内有意义。如果我必须这样做,我可能会使用加权移动平均线,所以(例如)我计算了最后5个鼠标移动消息中每一个的距离/时间,但它们的重要性随着时间的推移而“衰减”。例如,我可以将最近的乘以1,将下一个乘以.8,将下一个乘以.6,依此类推。这种方式如果(例如)它们恰好在释放按钮时减慢(或加速)移动,那么你仍然可以在它之前得到它们 所做的事情的合理近似。 / p>

答案 1 :(得分:5)

考虑使用GetMouseMovePointsEx()进行调整。它可以为您提供最多64点的移动历史记录。每个点都有一个时间戳,可以准确计算速度。它可以提高您的准确性,因为时间戳不会受到鼠标移动消息缓冲在消息队列中的任何延迟的影响。并且您可以使用本机鼠标单位而不是像素获取点数。访问pinvoke.net获取声明。

答案 2 :(得分:1)

我要做的是不断地对鼠标移动进行采样并跟踪 - 最后10个位置。然后,当释放鼠标按钮时,您将获得一系列测量值,以便在释放鼠标时估计鼠标速度。

我写了一个快速的winform应用程序来玩这个想法。这计算了 每次移动鼠标的速度。您需要使用队列长度。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace MouseVelocity
{
    public partial class Form1 : Form
    {
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        Queue timePoints;

        public Form1()
        {
            sw.Start();
            timePoints = new Queue(100);
            InitializeComponent();
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            addPoint(e);
        }

        private void addPoint(MouseEventArgs e)
        {
            timePoints.Enqueue(new TimePoint(new Point(e.X, e.Y), sw.ElapsedMilliseconds));
            if (timePoints.Count == 40) timePoints.Dequeue();
            object[] array = timePoints.ToArray();
            TimePoint tip = (TimePoint)array[array.Length - 1];
            TimePoint end = (TimePoint)array[0];
            long deltaX = tip.point.X - end.point.X;
            long deltaY = tip.point.Y - end.point.Y;

            long distance = deltaX * deltaX + deltaY * deltaY;

            long deltaT = tip.time - end.time;
            double velocity_modulo = Math.Sqrt(distance) / deltaT;
            double velocity_X = deltaX / (double)deltaT;
            double velocity_Y = deltaY / (double)deltaT;
            label1.Text = string.Format("|V| = {0}; Vx = {1}; Vy = {2}", velocity_modulo, velocity_X, velocity_Y);
        }

    }
    public class TimePoint
    {
        public Point point;
        public long time;

        public TimePoint(Point pt, long ms)
        {
            point = pt;
            time = ms;
        }
    }
}

答案 3 :(得分:0)

你要求计算距离 - 时间曲线曲线末端的速度,这在微积分中是不可能的

我建议你最好在曲线尽头采用一些短时间框架,最好的套装和计算速度几乎相同