触摸响应问题:如何解决锯齿状(非平滑)线条? [英] Touch responsiveness issue: How to resolve jagged (non-smooth) lines?
问题描述
Windows 8 touch API似乎存在与性能相关的触摸采样问题。下面是输出的示例:
产生此结果的代码如下所示:
< Page
x:Class =" GetIntermediatePointsReversed.MainPage"
xmlns =" http://schemas.microsoft.com/winfx/2006/xaml/presentation " ;
$
xmlns:x =" http://schemas.microsoft.com/winfx/2006/xaml "
xmlns:local =" using:GetIntermediatePointsReversed"
xmlns:d =" http://schemas.microsoft.com/expression/blend/2008 "
的xmlns:MC = QUOT; http://schemas.openxmlformats.org/markup-compatibility/2006 "
mc:Ignorable =" d">
< Grid Name =" drawContent"抽头= QUOT; TapToClear" Background =" {StaticResource ApplicationPageBackgroundThemeBrush}" />
$
< / Page>
使用System.Collections.Generic;
使用System.Diagnostics;
使用System.Linq;
使用Windows.Foundation;
使用Windows.UI;
使用Windows.UI.Input ; $
使用Windows.UI.Xaml;
使用Windows.UI.Xaml.Controls;
使用Windows.UI.Xaml.Input;
使用Windows.UI.Xaml.Media;
使用Windows.UI.Xaml.Shapes;
namespace GetIntermediatePointsReversed
{
公共密封的分类主页:页面
{
const uint radius = 26;
字典< Ellipse,uint> TouchPoints;
字典< uint,折线> LinePoints = new Dictionary< uint,Polyline>();
public MainPage()
{
this.InitializeComponent();
TouchPoints =新词典< Ellipse,uint>();
for(int i = 0; i< 40; i ++)
{
TouchPoints [new Ellipse()
{
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;宽度=半径,
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;高度=半径,
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; StrokeThickness = 2,
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;的HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Left,
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; &NBSP;&NBSP;&NBSP;&NBSP; VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Top,
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; &NBSP;&NBSP;&NBSP;&NBSP;行程=新的SolidColorBrush(Color.FromArgb(255,0,0,0)),
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;填=新的SolidColorBrush(Color.FromArgb(255,0,60,200)),
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;的RenderTransform =新TranslateTransform(){X = -radius / 2,Y = -radius / 2}
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ;&NBSP;&NBSP;&NBSP;&NBSP; }] = unchecked((uint)-1);
}
}
protected override void OnPointerPressed(PointerRoutedEventArgs e)
{
uint id = e.Pointer.PointerId;
if(CapturePointer(e.Pointer))
{
点tp = e.GetCurrentPoint(本).POSITION;
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ;&NBSP; DownMark(id,tp.X,tp.Y);
}
base.OnPointerPressed(e);
}
protected override void OnPointerMoved(PointerRoutedEventArgs e)
{
uint id = e.Pointer.PointerId;
var ipt = e.GetIntermediatePoints(this);
的Debug.WriteLine(QUOT;计数:" + ipt.Count());
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ; foreach(ipt.Reverse()中的PointerPoint指针点)
{
Point tp = pointerPoint.Position;
MoveMark(id,tp.X,tp.Y);
}
base.OnPointerMoved(e);
}
protected override void OnPointerReleased(PointerRoutedEventArgs e)
{
uint id = e.Pointer.PointerId;
UpMark(id);
ReleasePointerCapture(e.Pointer);
base.OnPointerReleased(e);
}
void DownMark(uint Id,double x1,double y1)
{
if(!TouchPoints.ContainsValue(Id))
{
VAR椭圆= TouchPoints.FirstOrDefault(即=> iE.Value ==取消选中((UINT)-1));
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; if(ellipse.Key!= null)
{
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; drawContent.Children.Add(ellipse.Key);
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ;&NBSP;&NBSP;&NBSP;接触点[ellipse.Key] =标识;
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; &NBSP;&NBSP;&NBSP;&NBSP; ellipse.Key.Margin =新厚度(X1,Y1,0,0);
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; &NBSP;&NBSP;&NBSP; }
//初始化折线的起点。
折线折线=新折线为&b $ b {
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;行程= this.Resources [" ApplicationForegroundThemeBrush"]如刷涂,
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; &NBSP;&NBSP;&NBSP;&NBSP;&NBSP; StrokeThickness = 4
}; b $ b polyline.Points.Add(新点(X1,Y1));
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; &NBSP;&NBSP;&NBSP; //添加以绘制内容和LinePoints字典
drawContent.Children.Add(折线);
LinePoints.Add(Id,折线);
}
}
void MoveMark(uint Id,double x1,double y1)
{
if(TouchPoints.ContainsValue(Id))
{
VAR椭圆= TouchPoints.First(即=> iE.Value == ID);
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ;&NBSP;&NBSP;&NBSP; ellipse.Key.Margin =新厚度(X1,Y1,0,0);
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; &NBSP;&NBSP;&NBSP; LinePoints [Id] .Points.Add(new Point(x1,y1));
}
}
void UpMark(uint Id)
{
if(TouchPoints.ContainsValue(Id))
{
LinePoints.Remove(ID);
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; VAR椭圆= TouchPoints.First(即=> iE.Value == ID);
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ;&NBSP;&NBSP;&NBSP; drawContent.Children.Remove(ellipse.Key);
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; TouchPoints [ellipse.Key] =未选中((uint)-1);
}
}
private void TapToClear(object sender,TappedRoutedEventArgs e)
{
如果(e.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ;&NBSP;&NBSP; drawContent.Children.Clear();
}
} b $ b}
使用非常类似的代码,Windows 7不会出现此问题。 使用WM_POINTERxxx事件的Windows 8桌面应用程序产生完全相同的结果。 有什么办法可以解决这个问题吗? FreshPaint和
的其他商店应用程序似乎都有解决此问题的方法。
这些应用程序能够在用户绘图时绘制平滑曲线(没有明显的后期处理输入)。
为什么Windows 8触控处理不如Windows 7?
没有应用程序可以做的任何事情来影响输入。您需要应用平滑算法。
如果使用InkManager,它可以为您平滑笔划并提供Bezier路径。
--Rob
There appears to be a performance related touch sampling problem with the Windows 8 touch APIs. Below is an example of the output:
The code that produced this result is shown below:
<Page
x:Class="GetIntermediatePointsReversed.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:GetIntermediatePointsReversed"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Name="drawContent" Tapped="TapToClear" Background="{StaticResource ApplicationPageBackgroundThemeBrush}" />
</Page>
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Input;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;
namespace GetIntermediatePointsReversed
{
public sealed partial class MainPage : Page
{
const uint radius = 26;
Dictionary<Ellipse, uint> TouchPoints;
Dictionary<uint, Polyline> LinePoints = new Dictionary<uint, Polyline>();
public MainPage()
{
this.InitializeComponent();
TouchPoints = new Dictionary<Ellipse, uint>();
for (int i = 0; i < 40; i++)
{
TouchPoints[new Ellipse()
{
Width = radius,
Height = radius,
StrokeThickness = 2,
HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Left,
VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Top,
Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0)),
Fill = new SolidColorBrush(Color.FromArgb(255, 0, 60, 200)),
RenderTransform = new TranslateTransform(){ X = -radius / 2, Y = -radius / 2}
}] = unchecked((uint)-1);
}
}
protected override void OnPointerPressed(PointerRoutedEventArgs e)
{
uint id = e.Pointer.PointerId;
if (CapturePointer(e.Pointer))
{
Point tp = e.GetCurrentPoint(this).Position;
DownMark(id, tp.X, tp.Y);
}
base.OnPointerPressed(e);
}
protected override void OnPointerMoved(PointerRoutedEventArgs e)
{
uint id = e.Pointer.PointerId;
var ipt = e.GetIntermediatePoints(this);
Debug.WriteLine("Count: " + ipt.Count());
foreach (PointerPoint pointerPoint in ipt.Reverse())
{
Point tp = pointerPoint.Position;
MoveMark(id, tp.X, tp.Y);
}
base.OnPointerMoved(e);
}
protected override void OnPointerReleased(PointerRoutedEventArgs e)
{
uint id = e.Pointer.PointerId;
UpMark(id);
ReleasePointerCapture(e.Pointer);
base.OnPointerReleased(e);
}
void DownMark(uint Id, double x1, double y1)
{
if (!TouchPoints.ContainsValue(Id))
{
var ellipse = TouchPoints.FirstOrDefault(iE => iE.Value == unchecked((uint)-1));
if (ellipse.Key != null)
{
drawContent.Children.Add(ellipse.Key);
TouchPoints[ellipse.Key] = Id;
ellipse.Key.Margin = new Thickness(x1, y1, 0, 0);
}
// Initialize starting point of polyline.
Polyline polyline = new Polyline
{
Stroke = this.Resources["ApplicationForegroundThemeBrush"] as Brush,
StrokeThickness = 4
};
polyline.Points.Add(new Point(x1, y1));
// Add to draw Content and LinePoints dictionary
drawContent.Children.Add(polyline);
LinePoints.Add(Id, polyline);
}
}
void MoveMark(uint Id, double x1, double y1)
{
if (TouchPoints.ContainsValue(Id))
{
var ellipse = TouchPoints.First(iE => iE.Value == Id);
ellipse.Key.Margin = new Thickness(x1, y1, 0, 0);
LinePoints[Id].Points.Add(new Point(x1, y1));
}
}
void UpMark(uint Id)
{
if (TouchPoints.ContainsValue(Id))
{
LinePoints.Remove(Id);
var ellipse = TouchPoints.First(iE => iE.Value == Id);
drawContent.Children.Remove(ellipse.Key);
TouchPoints[ellipse.Key] = unchecked((uint)-1);
}
}
private void TapToClear(object sender, TappedRoutedEventArgs e)
{
if (e.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
drawContent.Children.Clear();
}
}
}
Using very similar code, Windows 7 does not exhibit this problem. A Windows 8 desktop application that uses the WM_POINTERxxx events produces exactly the same result. Is there anything that can be done to fix this? FreshPaint and a couple other store applications appear to have a solution to this issue.
These apps are able to draw smooth curves as the user is drawing (no obvious post processing of input).
Why is Windows 8 touch processing inferior to Windows 7?There isn't anything the app can do to affect the input. You'll need to apply a smoothing algorithm.
If you use the InkManager it can smooth the strokes for you and provide a Bezier path.
--Rob
这篇关于触摸响应问题:如何解决锯齿状(非平滑)线条?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!