feat(web): gesture touchpath segmentation 🐵
This PR begins phase 2 of gesture-recognizer module development - adding analysis code that can segment the path taken by touchpoints (and mouse cursors) into "segments" that may be used to build & model full-fledged gestures.
The core features and functionality added here may be found in CumulativePathStats and PathSegmenter. It's taken a fair bit of research, trial, and error, but even in its present state, it's able to break the touchpath into reasonable... subsegments. You see, part of the problem is that motion involves both velocity and acceleration, and acceleration does not play nicely with the Normal distribution when you're statistically observing velocity.
That said, some of my trial cases thus far have given me perfect segmentation despite the acceleration / subsegment caveat. So far, it's not really failing to divide where I want it to; it's just dividing in a few places I don't want it to, though given the acceleration caveat it's reasonable. We'll just need an extra internal layer to compare the subsegment pieces to prevent unwanted splits due to acceleration. I've got prototyping code toward this, but it's still quite exploratory and incomplete.
Note that in the code's present state... it needs some reorganization / refactoring to better fit with our design goals for the gesture-recognizer module. I opted to go "quick and dirty" in order to determine what was most useful for segmentation and to develop the base segmentation logic without being overly constrained about organizational patterns at the same time, as this PR's additions, even to this point, have been in a state of flux for quite a while. (Not that they're out of the woods yet.)
@keymanapp-test-bot skip
User Test Results
Test specification and instructions
User tests are not required
Test Artifacts
- Android
- Developer
- iOS
- Keyboards
- Web
- Windows
Just realized one stats identity I used fairly regularly might be clarified by mentioning another Wikipedia article: one of the most underlying math / stat principles used may be found at https://en.wikipedia.org/wiki/Covariance. (This is also at the heart of buildRenormalized.)
Look at the second equation seen on the page. The same pattern holds for variance, too - just replace Y with X again. In case it helps with the parse, E[X] is basically the "sum of all values seen for X, divided by the number of values seen."
This is what allows us to safely 'batch' the statistical values (and 'unbatch' them with deaccumulate) instead of needing to loop over the samples in hindsight, facilitating a time complexity of O(1) instead of O(N) for nigh-all of the new methods.