Simpler, more accurate velocity calculations
This commit is contained in:
parent
0801a5617a
commit
936734c736
4 changed files with 21 additions and 44 deletions
|
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
## [Unreleased][]
|
## [Unreleased][]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Simpler, more accurate velocity calculations
|
||||||
|
|
||||||
## [2.0.0][] - 2016-11-05
|
## [2.0.0][] - 2016-11-05
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
<script src="../build.js"></script>
|
<script src="../build.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<a-scene physics="debug: true">
|
<a-scene physics="debug: true; gravity: -20">
|
||||||
|
|
||||||
<a-sphere
|
<a-sphere
|
||||||
click-drag
|
click-drag
|
||||||
dynamic-body="mass: 100"
|
dynamic-body="mass: 10"
|
||||||
position="0 3 -1"
|
position="0 3 -1"
|
||||||
radius="1.25"
|
radius="1"
|
||||||
color="#EF2D5E"
|
color="#EF2D5E"
|
||||||
>
|
>
|
||||||
</a-sphere>
|
</a-sphere>
|
||||||
|
@ -51,9 +51,9 @@
|
||||||
});
|
});
|
||||||
draggable.addEventListener('dragend', function(dragInfo) {
|
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
|
// reduce the velocity a little
|
||||||
var velocityDamp = 0.3;
|
var velocityDamp = 0.5;
|
||||||
|
|
||||||
var camera = draggable.sceneEl.camera;
|
var camera = draggable.sceneEl.camera;
|
||||||
|
|
||||||
|
|
|
@ -66,8 +66,7 @@
|
||||||
"version-changelog": "^2.0.1"
|
"version-changelog": "^2.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"deep-equal": "^1.0.1",
|
"deep-equal": "^1.0.1"
|
||||||
"simple-statistics": "^2.1.0"
|
|
||||||
},
|
},
|
||||||
"babel": {
|
"babel": {
|
||||||
"presets": [
|
"presets": [
|
||||||
|
|
48
src/index.js
48
src/index.js
|
@ -1,13 +1,11 @@
|
||||||
import deepEqual from 'deep-equal';
|
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 COMPONENT_NAME = 'click-drag';
|
||||||
const DRAG_START_EVENT = 'dragstart';
|
const DRAG_START_EVENT = 'dragstart';
|
||||||
const DRAG_MOVE_EVENT = 'dragmove';
|
const DRAG_MOVE_EVENT = 'dragmove';
|
||||||
const DRAG_END_EVENT = 'dragend';
|
const DRAG_END_EVENT = 'dragend';
|
||||||
|
|
||||||
const TIME_TO_KEEP_LOG = 300;
|
const TIME_TO_KEEP_LOG = 100;
|
||||||
|
|
||||||
function forceWorldUpdate(threeElement) {
|
function forceWorldUpdate(threeElement) {
|
||||||
|
|
||||||
|
@ -495,41 +493,21 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fitLineToVelocity(dimension) {
|
function calculateVelocity() {
|
||||||
|
|
||||||
if (positionLog.length < 2) {
|
if (positionLog.length < 2) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const velocities = positionLog
|
const start = positionLog[positionLog.length - 1];
|
||||||
|
const end = positionLog[0];
|
||||||
|
|
||||||
// Pull out just the x, y, or z values
|
const deltaTime = 1000 / (start.time - end.time);
|
||||||
.map(log => ({time: log.time, value: log.position[dimension]}))
|
return {
|
||||||
|
x: (start.position.x - end.position.x) * deltaTime, // m/s
|
||||||
// Then convert that into an array of array pairs [time, value]
|
y: (start.position.y - end.position.y) * deltaTime, // m/s
|
||||||
.reduce((memo, log, index, collection) => {
|
z: (start.position.z - end.position.z) * deltaTime, // m/s
|
||||||
|
};
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMouseUp({clientX, clientY}) {
|
function onMouseUp({clientX, clientY}) {
|
||||||
|
@ -540,11 +518,7 @@ const {didMount, didUnmount} = (function getDidMountAndUnmount() {
|
||||||
|
|
||||||
cleanUpPositionLog();
|
cleanUpPositionLog();
|
||||||
|
|
||||||
const velocity = {
|
const velocity = calculateVelocity();
|
||||||
x: fitLineToVelocity('x'),
|
|
||||||
y: fitLineToVelocity('y'),
|
|
||||||
z: fitLineToVelocity('z'),
|
|
||||||
};
|
|
||||||
|
|
||||||
draggedElement.emit(
|
draggedElement.emit(
|
||||||
DRAG_END_EVENT,
|
DRAG_END_EVENT,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue