简体   繁体   English

使用Windows Phone 8.1中的加速度传感器数据在画布上绘制线条

[英]Drawing lines in canvas using accelerometer sensor data in windows phone 8.1

I am drawing on canvas based on device movement, I want to draw different characters in canvas based on mobile movement. 我正在基于设备移动在画布上绘画,我想基于移动在画布上绘制不同的字符。

Currently its working, but I want to find time difference and i want to detect pause, pause means when user is not trying to draw and user is not moving mobile phone, so that Application ca assume that now user want to draw next character. 当前它正在工作,但是我想找到时差并且我想检测暂停,暂停表示当用户不尝试绘制并且用户不移动手机时,因此Application ca假定现在用户要绘制下一个字符。

How to find pause in accelerometer values. 如何找到加速度计值中的暂停。 Any logic? 有逻辑吗? Also tell me how i can smooth accelerometer values, so that user can draw lines without noise. 还告诉我如何使加速度计值平滑,以便用户可以画出没有噪声的线。

I cannot help with the accelerator part, but for the noise in the data, here is one approach using Weighted Moving Average . 对于加速器部分,我无能为力,但是对于数据中的噪声,这是使用加权移动平均值的一种方法。

The basics are simple: 基础很简单:

  • Find out how many points before current you want to use for smoothing 找出要使用的电流前要进行平滑处理的点数
  • Calculate a weight based on length, f.ex. 根据长度f.ex计算重量。 if length is 5 then the weight = 1+2+3+4+5 = 15 如果长度为5,则权重= 1 + 2 + 3 + 4 + 5 = 15
  • Iterate each data point starting from length of weight (you can start at 1 and cut the weighting short - below I'll demo the latter approach) 从权重的长度开始迭代每个数据点(您可以从1开始并缩短权重-下面我将演示后者的方法)
  • For point current - 5 multiply with 1/15, for current - 4 multiply with 2/15 and so forth. 对于点电流-5乘以1/15,对于点电流-4乘以2/15,依此类推。 The sum is stored as value for this point, repeat for the next value points 总和存储为该点的值,对下一个值点重复

Live demo 现场演示

Below is a demo (enter full page to see all graphics). 下面是一个演示(进入整页以查看所有图形)。 I wrote it in JavaScript so it could be shown live here in the answer. 我用JavaScript编写了它,因此可以在答案中实时显示它。 I think you should have little problem converting it into the language you're using (which is not stated). 我认为您将它转换为使用的语言应该没有什么问题(未说明)。

Move the slider to increase number of points to weight. 移动滑块以增加权重点数。 You can run the data through several passes to smooth even more. 您可以通过多次运行来运行数据,以进一步平滑数据。 The original data is a sinus curve with noise jitter. 原始数据是具有噪声抖动的正弦曲线。 With many points you can see the curve smooths to replicate this. 在许多点上,您可以看到曲线平滑以重复此操作。 Just using 9-10 points length over 2 passes will give a good result with very little time delay: 仅在2次传递中使用9-10点的长度即可获得良好的结果,并且延迟时间非常短:

 var ctx = document.querySelector("canvas").getContext("2d"), rng = document.querySelector("input"), val = document.querySelector("span"), data = [], scale = 30; // generate sinus wave with noise jitters for(var i = 0; i < ctx.canvas.width; i += 2) data.push(Math.sin(i*0.1) * Math.random() + Math.random()) // draw initial smoothed curve (length=1, no smoothing) drawWMA(); // calculate moving average function drawWMA() { var len = +rng.value, // get smoothing length (number of previous points) dataa = [], datab = [], // pass A and B arrays weight = 0; // calc weight based on length val.innerHTML = len; ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.beginPath(); // calc weight for(var i = 1; i <= len; i++) weight += i; // add range together [1, length] // plot original data at top of canvas plot(data, 30); // PASS 1: Calc new smoothed array dataa = calcWMA(data, len, weight); // plot smoothed curve ctx.fillText("FIRST PASS:", 0, 100); plot(dataa, 120); // PASS 2 (optional) datab = calcWMA(dataa, len, weight); ctx.fillText("SECOND PASS:", 0, 190); plot(datab, 210); ctx.stroke(); // render plots } function calcWMA(data, len, weight) { var i, t, datao = []; // calc new smoothed array for(i = 0; i < data.length; i++) { // iterate from length to end of data var v = 0; // calc average value for this position for(t = 0; t < len; t++) { // [1, len] if (it >= 0) v += data[it] * ((t+1) / weight); // weight previous values based on -delta } datao.push(v); // store new value } return datao } function plot(data, y) { ctx.moveTo(0, y + data[0]*scale); for(i = 1; i < data.length; i++) ctx.lineTo(i * 2, y + data[i]*scale); } rng.onchange = rng.oninput = drawWMA; 
 <label>Points to consider: <input type="range" min=1 max=50 value=1></label><span>1</span><br> <canvas width=600 height=300></canvas> 

A different approach would be to use a Savitzky–Golay filter which gives a similar result, but not "sacrifice" any points at the end (moving average will push forward or crop at the end). 一种不同的方法是使用Savitzky-Golay滤波器 ,该滤波器给出相似的结果,但不会在末端“牺牲”任何点(移动平均线将在末尾向前推动或裁剪)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM