为四川人民祈祷! www.onefoundation.cn
logo of kjam.org
Archive: 2008-5

Rubik's Cube modeling in python

虽然知道一定有人写过这样的东西, 好起兴依然驱使我花时间做这样一件事情.
Rubik's Cube 的数据结构如何表现, 在多次失败以后, 发现坐标绝对是超级好用的东西. 在图形编程中, 千万不能小看坐标的威力.
from math import *

class RubikCore(object): # example of define the data struct of a rubik's cube R = 0.5 # red G = 0,1,0 # green B = 0,0,1 # blue W = 0,0,0 # white Y = 1,1,0 # yellow D = 0,1,1 # dark brown cube = {} def __init__(self): self.init_cube() self.fill_face()
def init_cube(self): # create a matrix seq = (-1, 0, 1) for x in seq: for y in seq: for z in seq: self.cube[(x,y,z)] = {}
def fill_face(self): # fill color for every face seq = (-1, 0, 1) colors = {(1,0,0): self.R, (-1,0,0): self.G, (0,1,0): self.B, (0,-1,0): self.W, (0,0,1): self.Y, (0,0,-1): self.D,} for x in seq: for y in seq: for z in seq: for i,v in colors.iteritems(): self.cube[(x,y,z)][i] = v
def find(self, axis, value): # give axis and value find all the objects matched
AXIS = {'x':0, 'y':1, 'z':2} res = [] for i in self.cube: if i[AXIS[axis]] == value: res.append(i) return res def _rotate_plane(self, x1, y1): """ x'=xcosA-ysinA y'=ycosA+xsinA """ x2 = int(round( x1*cos(-pi/2) - y1*(sin(-pi/2)) )) y2 = int(round( y1*cos(-pi/2) + x1*(sin(-pi/2)) )) return x2,y2 def _rotate(self, axis, t): # pass a tuple(x,y,z) if axis == 'x': y,z = self. _rotate_plane(t[1],t[2]) return (t[0],y,z)
elif axis == 'y': x,z = self. _rotate_plane(t[0], t[2]) return (x, t[1], z)
elif axis == 'z': x,y = self. _rotate_plane(t[0], t[1]) return (x, y, t[2]) else: return None
def turn(self, axis, value): t = self.find(axis, value) n1 = {} for i in t: n1[self._rotate(axis, i)] = self.cube[i] n2 = {} #print self.cube[i] for l in self.cube[i]: n2[self._rotate(axis, l)] = self.cube[i][l] #print n2 self.cube[i].update(n2)
self.cube.update(n1)

写了一个数据结构的core, 要显示这个cube, 方法很多, 可以用OpenGL, 用PyGame, 只要继承这个类就可以了.

我自己在调试的时候使用了最偷懒的方法, NodeBox. 而且看起来, 想要找一个不错的3D引擎来搞定这些凡人的活, 还是很有挑战性的. OpenGL的抽象程度还是太低了, NodeBox在3D方面仍然缺乏足够的力量... 这样的工作如果使用Panda3D之类的东西来做, 是不是又有用牛刀的嫌疑?

或许我们真的需要一个能抽象OpenGL的python lib, free your mind的图像玩具, 就像Processing那样.

最后, 这样一个core code的确可以更好的优化一下, 比如把着色的顶点坐标都写进去. 不过剩下的已经基本是体力活了, 作为一个prototype, 要继续它最好是换一种语言(用Flex或者Processing, 至少作为劳动成果可以得到一个swf或者applet放在网上展示)

OK, 总算搞定一件一直都想做的事情.
comments: 2  
by kernel1983
12