0xAA55 发表于 2019-6-25 02:37:01

【翻译】Windows XP的“提高鼠标精确度”选项的原理——Pointer Ballistics

topofpage翻译原文:http://archive.is/20120907165307/msdn.microsoft.com/en-us/windows/hardware/gg463319.aspx
译者:0xAA55

Windows XP的指针弹道学

最后更新:2002年10月31日

本文提供:

[*]弹道性能综述
[*]Windows XP指针弹道学基础理论
[*]精密运动
[*]Windows XP弹道算法综述
[*]资源


sec1弹道性能综述
本文介绍了Microsoft Windows XP指针弹道的算法,适用于硬件工程师,驱动程序开发人员,测试经理和独立硬件供应商。新算法克服了先前操作系统中弹道算法的一些限制和反效果。本文介绍的指针弹道算法的主要功能,是保证无论鼠标的速度和采样率以及采样精度如何,它都能让鼠标移动更加精确平滑的一个算法。

作用

Windows XP的指针弹道算法的作用包含如下内容:

[*]支持在高分辨率和高DPI屏幕上也能进行快速的操作,同时还能保持像素级别的指针精度。
[*]让指针的移动更平滑。
[*]对指针的运动向量进行速度增益施加,而不是之前的只对x或y分量的单独缩放处理。
[*]当用户在进行对象选择操作上,让运动量降低到最低,允许用户进行像素尺度的精确选择。
[*]删除“高级”按钮并设计统一的加速度和速度滑块,以简化“鼠标属性”对话框中的用户界面。


问题

在Windows XP前的指针弹道算法存在如下的问题:

[*]加速度分别应用于X轴和Y轴而非基于向量,从而在斜向产生偏离。例如,在打开弹道的情况下,当你的鼠标绕圆圈运动的时候,鼠标指针画出来的图形看起来更像是圆角的方形而不是圆形。
[*]对于高分屏,用户需要更高速的指针运动速度,但旧的指针弹道算法在应用了加速度后,无法精确定位指针到像素级精度。它始终会跳过像素,导致无法进行精确到像素的定位。
[*]用于加速和速度设置的用户界面令人困惑,因为大多数用户在这种情况下不理解术语“加速”(acceleration)的含义。


sec2Windows XP指针弹道学基础理论
在Windows XP上,我们设置了一个函数用于对鼠标设备传来的实际速度值进行调整,来反映到实际的指针移动的行为上,并通过修改这个函数的算法来调整我们对加速度的实际处理方式。为了给鼠标移动的速度赋予物理意义来改进鼠标的设计,我们先把系统运算的单位转换为物理单位。

物理单位的关系

通过将鼠标的X或Y值称为mickey,并使用鼠标总线的更新速率和指针设备的分辨率对其进行缩放,将鼠标的单位转换为物理单位:

USB鼠标的典型总线更新速率为125 Hz,典型的指针分辨率为每英寸400 mickey。来自鼠标的每个数据包的mickey值的典型范围在0到+50之间,但在包结构中允许达到+127。例如,如果标准USB鼠标每包具有3 mickey的恒定输出,则该设备的物理速度为0.9375或约1英寸/秒。
要将屏幕坐标从任意单位转移到物理单位,使用以下关系:


例如,1024x768的典型17英寸显示器将具有大约80 DPI的分辨率和大约75Hz的刷新率。因此,如果数据未被转换(默认设置没有开启鼠标指针弹道),根据之前的例子,每包3个米奇,指针在屏幕上以2.8英寸/秒的速度物理移动。因此,使用USB鼠标和具有上述规格的17英寸屏幕,物理速度到虚拟速度的增益为3×(2.8 / 9.375)。也就是说,屏幕上指针的物理速度比鼠标的物理速度快三倍。

父转换函数

在建立好物理单位后,基于可用性研究构建父传递函数。父传输函数如下图所示:


转换函数由五点组成。五个点中的四个位于鼠标速度谱的下端。超出4英寸限制的速度是线性外推的。

曲线族

从父曲线推断出一族曲线,以产生具有不同速度和加速度特性的传递函数,如下图所示。用户使用“鼠标属性”对话框(“指针选项”选项卡)中的指针速度滑块来选择其中的曲线。


sec3精密运动
下图显示了转换函数图的关键拐点的特写。


第一个线段的斜率产生一个小于1的鼠标到屏幕的物理速度比,来提供精确移动和定位屏幕上每个像素的能力。当用户想要实现像素级精确的定位的时候,用户通过在物理上移动鼠标更远于屏幕上指针移动的距离,来保证鼠标指针在低速移动下的精确性和稳定性。计算的时候除出来的mickey数的余数要保留下来并且加到下一次移动时的mickey数上。

下图显示了曲线族的关键拐点的特写。需要注意的是,无论是鼠标移动速度的调整是快速还是慢速,靠前的部分都倾向于提高鼠标的精度(降低指针移动的速度)。这意味着无论鼠标速度设置如何,用户始终能够定位屏幕上的每个像素。


计算加速度

转换函数使用一个查找表来存储线段的各个节点,并使用线性插值来过渡节点之间的点。用于查找鼠标X和Y值的数值是输入的鼠标移动X和Y分量组成的矢量的模。在Windows XP前的指针弹道算法则是独立计算X和Y分量的加减速。因此,指针的移动偏向了数值更大的坐标轴,导致鼠标圆周运动的时候指针却进行了接近于圆角矩形的轨迹的运动。为了解决这个问题,X和Y组成向量的模,被用于计算加速度乘数,然后应用于平移X和Y数据。

定点数计算和数值范围

Windows XP的指针弹道算法在ring0到ring3之间。因此,浮点数计算并非随时可用,并且因为Windows XP的指针弹道算法需要求余除法,我们使用16.16定点数整数计算。这对于超像素级定位和增加鼠标移动平滑度非常重要。因此,计算结果的最大值是216(65536)。虽说存在溢出的可能,但它很难出现。就算对于将来,这种溢出能够造成问题,那也可以通过把定点数格式改为20.12来轻松解决。

修改转换函数

父曲线的数值被存储到注册表设定,它可以被用户使用GUI来轻易修改或客制化。这些特性能让程序员和用户控制鼠标弹道算法来适应大范围的不同需求。Windows XP存储5个16.16定点数格式的XY对。

>>>返回页首

sec4Windows XP弹道算法综述
以下列表按顺序总结了Windows XP中使用的弹道算法:


[*]系统启动或更改鼠标速度设置时,重新计算并存储转换表。父值存储在注册表中,并以物理单位存储,现在通过基于系统参数缩放它们来转换为虚拟单位:屏幕刷新率、屏幕分辨率、鼠标刷新率。鼠标默认为USB 125 Hz刷新率,默认的分辨率是400 dpi。(这可能会在将来改变来适应变化的实际情况。)然后根据鼠标属性对话框(指针选项页)中的指针滑块速度设置对曲线进行缩放。
[*]传入的鼠标X和Y值首先转换为定点数16.16格式。
[*]计算X和Y值组成的向量的模的大小并用于在查找表中查找加速度值。
[*]查找表由六个点组成(第一个是)。 每个点代表一个拐点,查找值通常位于拐点之间,因此使用线性插值来过渡。
[*]先前计算的余数将添加到鼠标移动量的X和Y,然后应用加速度乘数来转换值为指针运动量的X和Y。存储余数来叠加到下一个传入值。这是超像素级定位的方式。
[*]发送数值来移动指针。
[*]如果关闭该功能(通过去掉鼠标属性对话框[指针选项页]中鼠标速度滑块下方的提高指针精确度复选框),系统将像以前一样工作而不做速度变化计算,并绕过所有这些功能。系统将获取原始鼠标值,并将它们乘以基于速度滑块设置的标量来计算指针位置。


>>>返回页首

sec5资源
咨询:
发电子邮件。这一行我就不翻译了因为微软早停止对Windows XP的维护了。

资源:
Windows硬件驱动编写相关资源和文档:
https://developer.microsoft.com/en-us/windows/hardware

页: [1]
查看完整版本: 【翻译】Windows XP的“提高鼠标精确度”选项的原理——Pointer Ballistics