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

问题描述 投票:0回答:1

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

我将所有唯一的解决方案存储在内存中,将与给定结构进行比较,以确定可能有多少解决方案。

为此,我必须围绕每个面将立方体旋转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次。

java algorithm linear-algebra trigonometry euler-angles
1个回答
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不能满足您的要求,请相应地进行调整。

© www.soinside.com 2019 - 2024. All rights reserved.