动漫人物
为了开始表示旋转,我们必须确定一种比我们在屏幕上看到的更简单的有效方式。在计算图形时,机器并不总是渲染场景中的所有内容,而只会渲染视口中的内容。你的问题和其他许多人一样,必须从现实中抽象出来。在围棋术语中,我们将展平立方体并使用切片。切片救援使用切片,我们可以引用数组的块/部分并玩弄它们,移动,切割,相交等。我将使用一个 3x3 的立方体,其中数字“是颜色”,如果你可以通过每组 3 可视化一条虚线数字,你也可以想象把它折叠成一个真正的立方体。// cube represents a 3x3 3d cube// the view is 2d thovar 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 leftfunc 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 rightfunc 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 entirefunc 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)ositionfunc move(c int, p []int) { for i := range cube { cube[i][c] = p[i] }}所有这些都很酷且没有嵌套迭代,但这些都不起作用。原因是我们正在改变元素的位置,为了实现我们想要的,我们必须复制、重新创建(重新定位)或进行引用。我使用了没有指针的示例,试图使它们更简洁;您将在下面找到完整的功能示例。请记住,对于此类问题,可能存在许多不同的方法,可能是一种适当且高效的算法。这只是一个示例,说明如何利用 go slices 功能来简化数组操作并避免嵌套迭代等场景。package mainimport "fmt"// cube represents a 3x3 3d cube// the view is 2d thovar 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 leftfunc left(r int) { f := (*cube[r])[:3] *cube[r] = append((*cube[r])[3:], f...)}// moves the cube row to the rightfunc 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 cubefunc 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 entirefunc 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)ositionfunc 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