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

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