问题
I'm successfully detecting 0-360 degrees rotation (roll) of phone around an axis, but now I am having hard times designing an effective algorithm to detect one full turn. My working but I think not elegant and as effective algorithm as I would like is:
private boolean detectRoll;
private boolean[] checkpointsR = new boolean[4];
private boolean fullRollTurn;
public void detectingRoll() {
setDetectRoll(true);
checkpointsR[0] = true;
for (int i = 1; i < 4; i++) {
if (roll > 90 * i && roll < 90 * (i + 1)
&& checkpointsR[i - 1] == true) {
checkpointsR[i] = true;
}
}
if (areAllTrue(checkpointsR) && roll > 0 && roll < 45) {
fullRollTurn = true;
// reset rollCheckpoints
for (int i = 1; i < 4; i++) {
checkpointsR[i] = false;
}
}
}
public static boolean areAllTrue(boolean[] array) {
for (boolean b : array)
if (!b)
return false;
return true;
}
public void setDetectRoll(boolean detectRoll) {
this.detectRoll = detectRoll;
}
Any help would be really appreciated.
回答1:
Well, your code only detects turns that result from increasing roll
. In the other direction, ie a turn resulting from roll
falling,
if (checkpointsR[i - 1] == true)
{
checkpointsR[i] = true;
}
won't ever trigger.
While that's easily fixable, if the only sensor input you've got is roll
, the fixed-checkpoint is approach always going to have problems. The best way to visualize it is that your checkpoints are little red points on a circle, and the rotation of the phone corresponds to an ant crawling around the edge of the circle. Suppose that when the ant passes a point, it turns green, and that this represents the checkpoint being set to true
. If the ant starts between two checkpoints A
and B
, it can "fool" them by crawling through B
, all the way round to A
, and then turning around and heading the other way again. All the checkpoints will be green, but the ant won't have completed a full circle.
The way to resolve this is to change two things: first, give the checkpoints three states: unvisited
, clockwise
and anticlockwise
. Second, start the ant on top of a checkpoint.
Here're the new rules:
- Every point starts as
unvisited
(a red point). - If the ant passes a checkpoint in a clockwise direction, set it's state to
clockwise
(a little green arrow pointing clockwise from the point) - If the ant passes a checkpoint in the anticlockwise direction, set it's state to
anticlockwise
(a little green arrow pointing on the anticlockwise direction from the point) - A turn has been completed if all the checkpoints are
clockwise
or if they're allanticlockwise
.
This can be achieved with three checkpoints, and placed wherever you want on the circle as long as the first one is under the ant's initial position. I'd recommend {initial, inital + 120, initial + 240}
though for symmetry's sake.
(The ant thought-experiment works with two checkpoints, but when you've got two checkpoints the problem is there are a pair a regions with a non-unique checkpoint between them, which confuses the detection of which checkpoint the ant actually passed through when the ant goes from one region to the other)
来源:https://stackoverflow.com/questions/18847164/detect-360-degrees-turn-algorithm