Simpler, more accurate velocity calculations

This commit is contained in:
Jess Telford 2016-11-11 17:17:56 +11:00
parent 0801a5617a
commit 936734c736
4 changed files with 21 additions and 44 deletions

View file

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased][]
### Changed
- Simpler, more accurate velocity calculations
## [2.0.0][] - 2016-11-05
### Added

View file

@ -4,13 +4,13 @@
<script src="../build.js"></script>
</head>
<body>
<a-scene physics="debug: true">
<a-scene physics="debug: true; gravity: -20">
<a-sphere
click-drag
dynamic-body="mass: 100"
dynamic-body="mass: 10"
position="0 3 -1"
radius="1.25"
radius="1"
color="#EF2D5E"
>
</a-sphere>
@ -51,9 +51,9 @@
});
draggable.addEventListener('dragend', function(dragInfo) {
// We're dealing with a very heavy ball (mass: 100), so we want to
// We're dealing with a very heavy ball (mass: 10), so we want to
// reduce the velocity a little
var velocityDamp = 0.3;
var velocityDamp = 0.5;
var camera = draggable.sceneEl.camera;

View file

@ -66,8 +66,7 @@
"version-changelog": "^2.0.1"
},
"dependencies": {
"deep-equal": "^1.0.1",
"simple-statistics": "^2.1.0"
"deep-equal": "^1.0.1"
},
"babel": {
"presets": [

View file

@ -1,13 +1,11 @@
import deepEqual from 'deep-equal';
import linearRegression from 'simple-statistics/src/linear_regression';
import linearRegressionLine from 'simple-statistics/src/linear_regression_line';
const COMPONENT_NAME = 'click-drag';
const DRAG_START_EVENT = 'dragstart';
const DRAG_MOVE_EVENT = 'dragmove';
const DRAG_END_EVENT = 'dragend';
const TIME_TO_KEEP_LOG = 300;
const TIME_TO_KEEP_LOG = 100;
function forceWorldUpdate(threeElement) {
@ -495,41 +493,21 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
}
}
function fitLineToVelocity(dimension) {
function calculateVelocity() {
if (positionLog.length < 2) {
return 0;
}
const velocities = positionLog
const start = positionLog[positionLog.length - 1];
const end = positionLog[0];
// Pull out just the x, y, or z values
.map(log => ({time: log.time, value: log.position[dimension]}))
// Then convert that into an array of array pairs [time, value]
.reduce((memo, log, index, collection) => {
// skip the first item (we're looking for pairs)
if (index === 0) {
return memo;
}
const deltaPosition = log.value - collection[index - 1].value;
const deltaTime = (log.time - collection[index - 1].time) / 1000;
// The new value is the change in position
memo.push([log.time, deltaPosition / deltaTime]);
return memo;
}, []);
// Calculate the line function
const lineFunction = linearRegressionLine(linearRegression(velocities));
// Calculate what the point was at the end of the line
// ie; the velocity at the time the drag stopped
return lineFunction(positionLog[positionLog.length - 1].time);
const deltaTime = 1000 / (start.time - end.time);
return {
x: (start.position.x - end.position.x) * deltaTime, // m/s
y: (start.position.y - end.position.y) * deltaTime, // m/s
z: (start.position.z - end.position.z) * deltaTime, // m/s
};
}
function onMouseUp({clientX, clientY}) {
@ -540,11 +518,7 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
cleanUpPositionLog();
const velocity = {
x: fitLineToVelocity('x'),
y: fitLineToVelocity('y'),
z: fitLineToVelocity('z'),
};
const velocity = calculateVelocity();
draggedElement.emit(
DRAG_END_EVENT,