Drawing lines in canvas using accelerometer sensor data in windows phone 8.1

前端 未结 1 858
情话喂你
情话喂你 2021-01-29 03:06

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 d

相关标签:
1条回答
  • 2021-01-29 03:53

    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. if length is 5 then the weight = 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)
    • For point current - 5 multiply with 1/15, for current - 4 multiply with 2/15 and so forth. 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. 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:

    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 (i-t >= 0)
            v += data[i-t] * ((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).

    0 讨论(0)
提交回复
热议问题