I am trying to simulate Rubik's Cube. In order to detect if user has actually solved the Cube I would like to remember all initial position vectors and then just compare it.
However, when you start my program and mess the cube, then press 'k' to solve it you can see in the console that values in fact are the same, however they have different precision. For example z-value is -0.99999 instead of -1. The result of this flaw is that even though the values are quite the same, the program still won't consider the Cube solved. I guess that while rotating, when calculations are performed on the vector, the precision changes and as a result in the end the values are different. How can I solve this problem? To print out the initial position vectors and current vectors press 'a' key anytime you wish to :)
from visual import *
import string
import random
class Cube:
def __init__(self):
self.surfaces = { 'r': (color.red, (1, 0, 0)),
'o': (color.orange, (-1, 0, 0)),
'y': (color.yellow, (0, 1, 0)),
'b': (color.blue, (0, -1, 0)),
'w': (color.white, (0, 0, 1)),
'g': (color.green, (0, 0, -1))}
self.fps = 30
self.wholeSurfaces = []
self.initialPosition = []
self.commandsList = []
def createCube(self):
for colour, axis in self.surfaces.itervalues():
for x in (-1, 0, 1):
for y in (-1, 0, 1):
# Start with all powierzchniaBoczna on the top face, then rotate them "down"
# to the appropriate face.
powBoczna = box(color=colour, pos=(x, y, 1.5),
length=0.98, height=0.98, width=0.05)
cos_kat = dot((0, 0, 1), axis)
if cos_kat == 0: #alfa = 90 + kPI
obliczonaOsObrotu = cross((0, 0, 1), axis) #iloczyn wektorowy
else:
obliczonaOsObrotu=(1, 0, 0)
powBoczna.rotate(angle=acos(cos_kat), axis=obliczonaOsObrotu, origin=(0, 0, 0))
self.wholeSurfaces.append(powBoczna)
#remember initial position
v = (float(powBoczna.pos.x), float(powBoczna.pos.y), float(powBoczna.pos.z))
self.initialPosition.append(v)
def solveCube(self):
print self.commandsList
self.commandsList.reverse()
print self.commandsList
for i in self.commandsList:
self.rotateCube(self.reverseCommand(i), 10000)
self.commandsList = []
def reverseCommand(self, key):
if (key.islower()): return key.upper()
else: return key.lower()
def rotateCube(self, key, refreshRate):
colour, axis = self.surfaces[key.lower()]
if (key.isupper()): kat = (pi / 2.0)
else: kat = -pi/2.0
for r in arange(0, kat, kat / self.fps):
rate(refreshRate)
for surface in self.wholeSurfaces:
if dot(surface.pos, axis) > 0.5:
surface.rotate(angle=kat / self.fps, axis=axis, origin=(0, 0, 0))
def beginLoop(self):
while True:
key = scene.kb.getkey()
if (key.lower() in self.surfaces):
self.commandsList.append(key)
self.rotateCube(key, self.fps)
elif key == "k":
self.solveCube()
elif key == "a":
i = 0
print "================="
for surface in self.wholeSurfaces:
print "%s\n(%s,%s,%s)" % (self.initialPosition[i], surface.pos.x, surface.pos.y, surface.pos.z)
if self.initialPosition[i][0] == float(surface.pos.x) and self.initialPosition[i][1] == float(surface.pos.y) and self.initialPosition[i][2] == float(surface.pos.z): print "equal"
else: print "not equal"
print ""
i+=1
if __name__ == "__main__":
myCube = Cube()
myCube.createCube()
myCube.beginLoop()