为了账号安全,请及时绑定邮箱和手机立即绑定

旋转 3 维数组

旋转 3 维数组

Go
德玛西亚99 2022-07-11 17:38:42
我正在使用它们来制作一个功能性的魔方立方体,但我无法将我的头绕在我将如何旋转立方体以查看其他方面的问题上。我创建了一个包含 27 个立方体的数组,每个立方体有 6 个边,它们的外侧面都写有颜色,我想知道是否有一种更简单的方法可以让我旋转立方体中的所有值而不是全部旋转每个立方体的面并手动将它们更改为所需的面。这是创建多维数据集的代码,如果您能想到一种方法,请告诉我,提前谢谢。func constructcube() (newcube [3][3][3][6]string) {    for d := 0; d < 3; d++ {        for h := 0; h < 3; h++ {            for w := 0; w < 3; w++ {                for f := 0; f < 6; f++ {                    newcube[d][h][w][f] = " "                    switch f {                    case 0:                        if d == 2 {                            newcube[d][h][w][f] = "m"                        }                    case 1:                        if w == 0 {                            newcube[d][h][w][f] = "y"                        }                    case 2:                        if d == 0 {                            newcube[d][h][w][f] = "r"                        }                    case 3:                        if w == 2 {                            newcube[d][h][w][f] = "c"                        }                    case 4:                        if h == 0 {                            newcube[d][h][w][f] = "b"                        }                    case 5:                        if h == 2 {                            newcube[d][h][w][f] = "g"                        }                    }                }            }        }    }    return newcube}
查看完整描述

2 回答

?
动漫人物

TA贡献1815条经验 获得超10个赞

为了开始表示旋转,我们必须确定一种比我们在屏幕上看到的更简单的有效方式。在计算图形时,机器并不总是渲染场景中的所有内容,而只会渲染视口中的内容。你的问题和其他许多人一样,必须从现实中抽象出来。在围棋术语中,我们将展平立方体并使用切片。

切片救援

使用切片,我们可以引用数组的块/部分并玩弄它们,移动,切割,相交等。我将使用一个 3x3 的立方体,其中数字“是颜色”,如果你可以通过每组 3 可视化一条虚线数字,你也可以想象把它折叠成一个真正的立方体。

// cube represents a 3x3 3d cube

// the view is 2d tho

var cube = [][]int{

    {1,1,1,2,2,2,3,3,3,4,4,4},

    {1,1,1,2,2,2,3,3,3,4,4,4},

    {1,1,1,2,2,2,3,3,3,4,4,4},

    {2,2,2},

    {2,2,2},

    {2,2,2},

    {3,3,3},

    {3,3,3},

    {3,3,3},

    {4,4,4},

    {4,4,4},

    {4,4,4},

}

玩立方体意味着完全移动一列或一行,但在视口中显示的只是立方体的前面——我们将在后面的步骤中处理它。向左移动一行,移动该行的每个元素,我们使用切片


// moves the cube row to the left

func left(r int)  {

    f := cube[r][:3] // slice the first 3 elements of the row

    cube[r] = append(cube[r][3:], f...) // append those to the back, while removing the first 3 and creating a new slice

}

这种模式在与立方体的所有交互中重复


// moves the cube row to the right

func right(r int)  {

    b := cube[r][len(cube[r])-3:]

    cube[r] = append(b, cube[r][:len(cube[r])-3]...)

}

向右移动,我们从后面获取元素并将它们放在前面......向前(向上)和向后(向下)移动我们将检索整个列并应用相同的方法


// forward moves the cube's (c)column forward(up)

func forward(c int)  {

    r := flatten(c) // retrieve the whole column

    a := r[:3]

    r = append(r[3:], a...)

    move(c, r) // apply the new position

}


// flatten percolates the (c)olumn position and return a flatten slice of its entire

func flatten(c int) []int {

    var r []int

    for _, v := range cube {

        r = append(r, v[c])

    }


    return r

}


// move moves the cube (c)olumn to (p)osition

func move(c int, p []int)  {

    for i := range cube {

        cube[i][c] = p[i]

    }

}

所有这些都很酷且没有嵌套迭代,但这些都不起作用。原因是我们正在改变元素的位置,为了实现我们想要的,我们必须复制、重新创建(重新定位)或进行引用。


我使用了没有指针的示例,试图使它们更简洁;您将在下面找到完整的功能示例。


请记住,对于此类问题,可能存在许多不同的方法,可能是一种适当且高效的算法。这只是一个示例,说明如何利用 go slices 功能来简化数组操作并避免嵌套迭代等场景。


package main


import "fmt"


// cube represents a 3x3 3d cube

// the view is 2d tho

var cube = []*[]int{

    {1,1,1,2,2,2,3,3,3,4,4,4},

    {1,1,1,2,2,2,3,3,3,4,4,4},

    {1,1,1,2,2,2,3,3,3,4,4,4},

    {2,2,2},

    {2,2,2},

    {2,2,2},

    {3,3,3},

    {3,3,3},

    {3,3,3},

    {4,4,4},

    {4,4,4},

    {4,4,4},

}


func main() {

    display()

    forward(1)

    left(1)

    display()

    backward(1)

    display()

}


// moves the cube's (c)olumn backwards(down)

func backward(c int)  {

    r := flatten(c)

    a := r[len(r)-3:]

    r = append(a, r[:len(r)-3]...)

    move(c, r)

}


// forward moves the cube's (c)column forward(up)

func forward(c int)  {

    r := flatten(c)

    a := r[:3]

    r = append(r[3:], a...)

    move(c, r)

}


// moves the cube row to the left

func left(r int)  {

    f := (*cube[r])[:3]

    *cube[r] = append((*cube[r])[3:], f...)

}


// moves the cube row to the right

func right(r int)  {

    b := (*cube[r])[len(*cube[r])-3:]

    *cube[r] = append(b, (*cube[r])[:len(*cube[r])-3]...)

}


// display the front view of the cube

func display()  {

    for y := 0; y < 3; y++ {

        fmt.Printf("[")

        for x := 0; x < 3; x++ {

            fmt.Printf("%d", (*cube[y])[x])

            if x < 2 {

                fmt.Printf("\t")

            }

        }

        fmt.Println("]")

    }

    fmt.Println()

}


// flatten percolates the (c)olumn position and return a flatten slice of its entire

func flatten(c int) []int {

    var r []int

    for _, v := range cube {

        r = append(r, (*v)[c])

    }


    return r

}


// move moves the cube (c)olumn to (p)osition

func move(c int, p []int)  {

    for i := range cube {

        (*cube[i])[c] = p[i]

    }

}

免责声明


该脚本依赖于cube具有 3x3 正方形面的变量的存在。没有进行索引检查,警告out of bounds恐慌。


https://play.golang.com/p/Z7azOi0omP3


查看完整回答
反对 回复 2022-07-11
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

我最终弄清楚如何使用称为“旋转矩阵”的东西来做到这一点,您可以在图中获取每个点的坐标并将其从 {i, j, k} 更改为 {i, k, -j} 并旋转3维对象。我不得不使用一些测试输入并将其与实际输出对齐,并且由于在这种情况下值不能为负,我发现您只需从立方体侧的上限中减去它们,即 2 .



查看完整回答
反对 回复 2022-07-11
  • 2 回答
  • 0 关注
  • 207 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号