【问题标题】:How to compute all orientations of a cube by rotating, without repeating orientations?如何通过旋转而不重复方向来计算立方体的所有方向?
【发布时间】:2019-02-02 19:39:26
【问题描述】:

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

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

为了做到这一点,我必须将立方体围绕每个面旋转 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】:

    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 没有为你做它应该做的事情,那么请相应地调整它。

    【讨论】:

      猜你喜欢
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-17
      • 1970-01-01
      • 2015-09-07
      • 1970-01-01
      相关资源
      最近更新 更多