如何通过旋转来计算立方体的所有方向,而无需重复方向?

时间:2019-02-02 19:39:26

标签: java algorithm trigonometry linear euler-angles

我正在开发一个应用程序,以找到给定特定起始结构的拼图立方体的可能解决方案的数量。

我都存储在存储器中的独特的解决方案,这是我将在给定的结构对,以确定有多少解决方案是可能的比较

为此,我必须将立方体绕每个面旋转90度4次,以便检查所有可能的方向。我将在稍后考虑反射。

通过立方体,有6个面与4个旋转给出总共24个操作。

我挣扎实现一个有效的算法,由于以下事实:一个绕一个轴旋转等同于关于其它轴2旋转。

例如:一个绕x轴的旋转产生了相同的方向绕y轴,然后z轴。这样我的当前实施所需64点的操作,其是因为我多次检查相同的方向的冗余。

Image of application

当前算法:

public static int getPossibleSolutionCount(Map<PieceIndex, Piece> pieces)
{
    int count = 0;
    for (Solution s : solutions)
    {
        for (int z = 0; z < 4; z++)
        {
            for (int x = 0; x < 4; x++)
            {
                for (int y = 0; y < 4; y++)
                {
                    if (s.isDerrivedFrom(pieces))
                    {
                        count++;
                    }
                    //all rotation calls rotate the piece / structure byt 90 degrees
                    pieces.values().forEach(piece -> piece.rotate(GameObject.Axis.Y_AXIS));
                }
                pieces.values().forEach(piece -> piece.rotate(GameObject.Axis.X_AXIS));
            }
            pieces.values().forEach(piece -> piece.rotate(GameObject.Axis.Z_AXIS));
        }
    }
    return count;
}

如何使得我不重复相同的取向改善这一点,即,使得我可以检查而仅24次迭代超过64个。

1 个答案:

答案 0 :(得分:1)

的24转的每一个都可以被唯一地识别由面部朝上(6个可能性),和面对左(4种可能性每个向上的面)。

使用外部循环确定朝上的面孔,然后通过内部循环确定朝左的面孔,似乎很容易。给定您的旋转调用需要的参数,我可能会这样:

// Rotating around these axes in sequence will bring each face in turn
// to the top
private static GameObject.AXIS ROTATION_PATH = new GameObject.AXIS[] {
    GameObject.AXIS.X_AXIS,
    GameObject.AXIS.X_AXIS,
    GameObject.AXIS.Z_AXIS,
    GameObject.AXIS.X_AXIS,
    GameObject.AXIS.X_AXIS,
    GameObject.AXIS.Z_AXIS
};

public static int getPossibleSolutionCount(Map<PieceIndex, Piece> pieces)
{
    int count = 0;
    for (GameObject.AXIS path_axis: ROTATION_PATH)
    {
        for (int y = 0; y < 4; y++)
        {
            for (Solution s : solutions)
            {
               if (s.isDerivedFrom(pieces))
               {
                   count++;
               }
            }
            pieces.values().forEach(piece -> piece.rotate(GameObject.Axis.Y_AXIS));
        }
        pieces.values().forEach(piece -> piece.rotate(path_axis));
    }
    return count;
}

希望你看到它是如何工作的。我做了哪些方法您轴指向哪个方向旋转起来了,所以如果ROTATION_PATH不会做它应该给你,然后相应地调整。

假设和