如何使用加速度计确定八面体和十二面体的边?

How to determine the side of an octahedron and a dodecahedron using an accelerometer?

我有三个图形:一个立方体,一个八面体,一个十二面体。

在里面,每个人偶都有一个加速度计。

编号在 1 到 n 之间的数字的边。

任务:判断立方体的当前面,八面体,十二面体。

对于立方体,我推导出公式:

side = round((Ax*1/988)+(Ay*2/988)+(Az*3/988));

变量"side"将给出区间-3和3之间的值(没有0),这意味着立方体的当前边在1和6之间。

现在我需要对八面体和十二面体做同样的事情。求助,我该怎么做?我需要额外的传感器还是加速度计就足够了?

使用这样的公式非常聪明,但它有一些不受欢迎的特性。首先,当从一侧移动到另一侧时,由于公式的原因,它会移动一些中间值,这些值在几何上是没有意义的。例如,如果您在 -3 侧并旋转到 -1 侧,则它必然会移动到 -2 侧。其次,它可能对嘈杂的加速度计数据不稳健,例如,在边 -3 和 -1 之间的矢量,但更接近 -1 可能会给出 -2,而它应该给出 -1。

另一种方法是存储图形的面部法线数组,然后对每个法线取加速度计读数的点积。最接近的匹配项(点积最高的那个)是最接近的边。

例如:

float cube_sides[6][3] = {
    {-1, 0, 0},
    {0, -1, 0},
    {0, 0, -1},
    {1, 0, 0},
    {0, 1, 0},
    {0, 0, 1},
};

int closest_cube_side(float Ax, float Ay, float Az)
{
    float largest_dot = 0;
    int closest_side = -1; // will return -1 in case of a zero A vector
    for(int side = 0; side < 6; side++)
    {
        float dot = (cube_sides[side][0] * Ax) +
            (cube_sides[side][1] * Ay) +
            (cube_sides[side][2] * Az);
        if(dot > largest_dot)
        {
            largest_dot = dot;
            closest_side = side;
        }            
    }
    return closest_side;
}

您可以将其扩展为八面体和十二面体,只需使用每个表面法线即可。不需要额外的传感器。