Python - Como hacer un cubo rubik

 
Vista:
Imágen de perfil de Geraldine
Val: 6
Ha disminuido su posición en 20 puestos en Python (en relación al último mes)
Gráfica de Python

Como hacer un cubo rubik

Publicado por Geraldine (4 intervenciones) el 13/12/2018 01:19:02
Como están compañeros? Quisiera saber cómo o para qué se usan las siguientes lineas de código:

Por cierto, por que se multiplica en la linea 10 y 11 por 0.5?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import numpy as np #Esta extension sirve para agregar mayor soporte a vectores y matrices 
 
class Quaternion:
 
    @classmethod
    def from_v_theta(cls, v, theta):
 
        theta = np.asarray(theta) #asarray convierte la entrada a una matriz. En este caso, el parametro afectado sera Theta.
        v = np.asarray(v)
        s = np.sin(0.5 * theta) #Multiplicamos Seno 0.5 por theta.  
        c = np.cos(0.5 * theta) #Multiplicamos Coseno 0.5 por theta.
 
        v = v * s / np.sqrt(np.sum(v * v, -1)) #sqrt Devuelve la raíz cuadrada del número x.
        x_shape = v.shape[:-1] + (4,)
 
        x = np.ones(x_shape).reshape(-1, 4) #ones Devuelve un nuevo conjunto de shapes (formas) y tipos
        x[:, 0] = c.ravel() # ravel Devuelve una matriz aplanada contigua. Se devuelve una matriz 1-D, que contiene los elementos de 
                            #la entrada. Solo se hace una copia si es necesario.
        x[:, 1:] = v.reshape(-1, 3) # reshape Da una nueva forma a una matriz sin cambiar sus datos.
        x = x.reshape(x_shape)
 
        return cls(x)
 
    def __init__(self, x): #__init__ Se encarga de inicializar los atributos del objeto que creamos. No retorna ningun dato.
        self.x = np.asarray(x, dtype=float) #Con dtype podemos conocer que tipo de dato es, en este caso asignamos que es un float.
 
    def __repr__(self): #__repr__ retorna un string que describe el objeto según el formato por defecto.
        return "Quaternion:\n" + self.x.__repr__() #Llamamos al metodo __repr__.
 
    def __mul__(self, other):#__mul__ retorna una multiplicacion entre self * other.
        # Multiplicación de dos cuaterniones. No se implementa la multiplicación por un escalar.
        sxr = self.x.reshape(self.x.shape[:-1] + (4, 1))
        oxr = other.x.reshape(other.x.shape[:-1] + (1, 4))
 
        prod = sxr * oxr #prod es el producto obtenido entre sxr * oxr
        return_shape = prod.shape[:-1]
        prod = prod.reshape((-1, 4, 4)).transpose((1, 2, 0)) #transpose Permuta las dimensiones de una matriz.
 
        ret = np.array([(prod[0, 0] - prod[1, 1]
                         - prod[2, 2] - prod[3, 3]),
                        (prod[0, 1] + prod[1, 0]
                         + prod[2, 3] - prod[3, 2]),
                        (prod[0, 2] - prod[1, 3]
                         + prod[2, 0] + prod[3, 1]),
                        (prod[0, 3] + prod[1, 2]
                         - prod[2, 1] + prod[3, 0])],
                       dtype=np.float,
                       order='F').T
        return self.__class__(ret.reshape(return_shape))
 
    def as_v_theta(self):
        """Devuelve v, theta equivalente del cuaternión"""
        x = self.x.reshape((-1, 4)).T
 
        # Calculamos theta:
        norm = np.sqrt((x ** 2).sum(0))
        theta = 2 * np.arccos(x[0] / norm)
 
        # Calculamos el vector unitario:
        v = np.array(x[1:], order='F', copy=True)
        v /= np.sqrt(np.sum(v ** 2, 0))
 
        # Mostramos la nueva forma (reshape):
        v = v.T.reshape(self.x.shape[:-1] + (3,))
        theta = theta.reshape(self.x.shape[:-1])
 
        return v, theta
 
    def as_rotation_matrix(self):
        """Devuelve la matriz de rotación del cuaternión"""
        v, theta = self.as_v_theta() #Instanciamos la clase as_v_theta. 
 
        shape = theta.shape
        theta = theta.reshape(-1)
        v = v.reshape(-1, 3).T
        c = np.cos(theta)
        s = np.sin(theta)
 
        mat = np.array([[v[0] * v[0] * (1. - c) + c,
                         v[0] * v[1] * (1. - c) - v[2] * s,
                         v[0] * v[2] * (1. - c) + v[1] * s],
                        [v[1] * v[0] * (1. - c) + v[2] * s,
                         v[1] * v[1] * (1. - c) + c,
                         v[1] * v[2] * (1. - c) - v[0] * s],
                        [v[2] * v[0] * (1. - c) - v[1] * s,
                         v[2] * v[1] * (1. - c) + v[0] * s,
                         v[2] * v[2] * (1. - c) + c]],
                       order='F').T
        return mat.reshape(shape + (3, 3))
 
    def rotate(self, points):
        M = self.as_rotation_matrix() #Creamos una matriz de rotacion.
        return np.dot(points, M.T)
 
 
def Puntos_Proyeccion(points, q, view, vertical=[0, 1, 0]):
 
    points = np.asarray(points)
    view = np.asarray(view)
 
    xdir = np.cross(vertical, view).astype(float) #cross Devuelve el producto cruzado de dos (arreglos de) vectores.
                                                  #astype Copia la matriz y luego la convierte a un tipo de dato especificado.
    if np.all(xdir == 0): #all Comprueba si todos los elementos de la matriz a lo largo de un eje asignado se evalúan como Verdaderos.
        raise ValueError("Vertical es paralelo a v")
 
    xdir /= np.sqrt(np.dot(xdir, xdir)) #dot Es el producto entre dos matrices.
 
    # Obtenemos el vector unitario correspondiente a vertical.
    ydir = np.cross(view, xdir)
    ydir /= np.sqrt(np.dot(ydir, ydir))
 
    # Normalizamos la ubicación del visor: Este es el eje z.
    v2 = np.dot(view, view)
    zdir = view / np.sqrt(v2)
 
    # Rotamos los puntos.
    R = q.as_rotation_matrix()
    Rpts = np.dot(points, R.T)
 
    # Proyectamos los puntos sobre la vista.
    dpoint = Rpts - view
    dpoint_view = np.dot(dpoint, view).reshape(dpoint.shape[:-1] + (1,))
    dproj = -dpoint * v2 / dpoint_view
 
    trans =  list(range(1, dproj.ndim)) + [0] #Creamos una lista.
    return np.array([np.dot(dproj, xdir),
                     np.dot(dproj, ydir),
                     -np.dot(dpoint, zdir)]).transpose(trans)
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder