触摸响应问题:如何解决锯齿状(非平滑)线条? [英] Touch responsiveness issue: How to resolve jagged (non-smooth) lines?

查看:103
本文介绍了触摸响应问题:如何解决锯齿状(非平滑)线条?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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;的Horizo​​ntalAlignment = Windows.UI.Xaml.Horizo​​ntalAlignment.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆