0

我正在尝试模拟魔方。为了检测用户是否真正解决了立方体,我想记住所有初始位置向量,然后进行比较。

但是,当您启动我的程序并弄乱立方体时,然后按“k”来解决它,您可以在控制台中看到值实际上是相同的,但是它们具有不同的精度。例如,z 值为 -0.99999 而不是 -1。这个缺陷的结果是,即使值非常相同,程序仍然不会认为 Cube 已解决。我猜想在旋转时,对向量执行计算时,精度会发生变化,因此最终值会有所不同。我怎么解决这个问题?要打印出初始位置向量和当前向量,请随时按“a”键 :)

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()
4

1 回答 1

0

解决方案很简单,您需要使用具有给定精度的numpy.allclose方法。

for surface in self.wholeSurfaces:
    print "%s\n%s" % (self.initialPosition[i], powierzchnia.pos)
    if np.allclose(self.initialPosition[i], surface.pos.astuple(), 1e-5, 1e-5): print "are equal"
    else: print "arent equal"
    i+=1
于 2015-05-30T17:25:04.773 回答