Rubik's Cube modeling in python
虽然知道一定有人写过这样的东西, 好起兴依然驱使我花时间做这样一件事情.
Rubik's Cube 的数据结构如何表现, 在多次失败以后, 发现坐标绝对是超级好用的东西. 在图形编程中, 千万不能小看坐标的威力.
写了一个数据结构的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, 总算搞定一件一直都想做的事情.
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, 总算搞定一件一直都想做的事情.
feed
旋转当然只能是一个面, 要转一下就是90度, 如果以后打算动画显示的话, 还是要增加一些东西的. 不过这样的一个class至少可以帮我们运算运算魔方的状态.
想改用processing来写一个applet放在网页里面跑, 不知道周某有没有时间.