简体   繁体   English

如何在vPython中比较两个向量

[英]How to compare two vectors in vPython

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. 但是,当您启动程序并弄乱多维数据集,然后按“ k”进行求解时,您可以在控制台中看到实际上值是相同的,但是它们具有不同的精度。 For example z-value is -0.99999 instead of -1. 例如,z值为-0.99999而不是-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 :) 要打印出初始位置矢量和当前矢量,请随时按“ 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()

The solution is simple, you need to use numpy.allclose method with given precision. 解决方案很简单,您需要以给定的精度使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM