Ejemplo n.º 1
0
 def __init__(self, x=0, y=None, by_ref=False):
     if y is None:
         if isinstance(x, Coord):
             self.x = x.copy()
             self.y = x.copy()
         else:
             self.x = Coord(x)
             self.y = Coord(x)
         return
     if not by_ref:
         self.x = x
         self.y = y
     if isinstance(x, Coord):
         self._x = x
     else:
         self.x = x
     if isinstance(y, Coord):
         self._y = y
     else:
         self.y = y
Ejemplo n.º 2
0
 def __init__(self, x=0, y=None, z=None, by_ref=False):
     if y is None and z is None:
         if isinstance(x, Coord):
             self.x = x.copy()
             self.y = x.copy()
             self.z = x.copy()
         else:
             self.x = Coord(x)
             self.y = Coord(x)
             self.z = Coord(x)
         return
     if y is None:
         y = 0
     if z is None:
         z = 0
     if not by_ref:
         self.x = x
         self.y = y
         self.z = z
         return
     if isinstance(x, Coord):
         self._x = x
     else:
         self.x = x
     if isinstance(y, Coord):
         self._y = y
     else:
         self.y = y
     if isinstance(z, Coord):
         self._z = z
     else:
         self.z = z
Ejemplo n.º 3
0
 def rotated(self, angle, point_vec=None, radians=True):
     if not radians:
         angle = math.radians(angle)
     angle = Coord(angle).value
     if point_vec is None:
         point_vec = Vector2()
     assert isinstance(point_vec, Vector2), "point_vec must be a Vector2"
     result = self.copy()
     result -= point_vec
     new_x = result.x * math.cos(angle) + result.y * math.sin(angle)
     new_y = result.x * -math.sin(angle) + result.y * math.cos(angle)
     result.x, result.y = new_x, new_y
     result += point_vec
     result.x._prefix = self.x._prefix
     result.y._prefix = self.y._prefix
     return result
Ejemplo n.º 4
0
 def z(self, value):
     self._z = Coord(value)
Ejemplo n.º 5
0
 def y(self, value):
     self._y = Coord(value)
Ejemplo n.º 6
0
 def x(self, value):
     self._x = Coord(value)
Ejemplo n.º 7
0
class Vector3(Vector):
    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x = Coord(value)

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, value):
        self._y = Coord(value)

    @property
    def z(self):
        return self._z

    @z.setter
    def z(self, value):
        self._z = Coord(value)

    def __init__(self, x=0, y=None, z=None, by_ref=False):
        if y is None and z is None:
            if isinstance(x, Coord):
                self.x = x.copy()
                self.y = x.copy()
                self.z = x.copy()
            else:
                self.x = Coord(x)
                self.y = Coord(x)
                self.z = Coord(x)
            return
        if y is None:
            y = 0
        if z is None:
            z = 0
        if not by_ref:
            self.x = x
            self.y = y
            self.z = z
            return
        if isinstance(x, Coord):
            self._x = x
        else:
            self.x = x
        if isinstance(y, Coord):
            self._y = y
        else:
            self.y = y
        if isinstance(z, Coord):
            self._z = z
        else:
            self.z = z

    def cross(self, vec3):
        if not isinstance(vector3, Vector3):
            raise TypeError("A cross product is only applicable to a Vector3")
        x = self.y * vector3.z - self.z * vector3.y
        y = self.z * vector3.x - self.x * vector3.z
        z = self.x * vector3.y - self.y * vector3.x
        return Vector3(x, y, z)

    def dot(self, vec):
        if not isinstance(vec, Vector3):
            raise TypeError("Vector sizes must match")
        return self.x * vec.x + self.y * vec.y + self.z * vec.z

    def copy(self):
        return Vector3(self.x.copy(), self.y.copy(), self.z.copy())

    def __len__(self):
        return 3

    def __iter__(self):
        yield self.x
        yield self.y
        yield self.z

    def __getitem__(self, key):
        keys = "xyz"
        if isinstance(key, int):
            key = keys[key]
        if key == "x":
            return self.x
        elif key == "y":
            return self.y
        elif key == "z":
            return self.z
        else:
            raise IndexError("Vector3 does not contain {}".format(key))

    def __setitem__(self, key, value):
        keys = "xyz"
        if isinstance(key, int):
            key = keys[key]
        if key == "x":
            self.x = value
        elif key == "y":
            self.y = value
        elif key == "z":
            self.z = value
        else:
            raise IndexError("Vector3 does not contain {}".format(key))

    def __repr__(self):
        return "Vector3('{}','{}','{}')".format(str(self.x), str(self.y),
                                                str(self.z))

    def __str__(self):
        return "({},{},{})".format(str(self.x), str(self.y), str(self.z))

    def simple_str(self):
        return "{} {} {}".format(str(self.x), str(self.y), str(self.z))

    @property
    def xxx(self):
        return Vector3(self.x, self.x, self.x)

    @xxx.setter
    def xxx(self, value):
        raise RuntimeError(
            "Elements in this vector 'xxx' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def xxy(self):
        return Vector3(self.x, self.x, self.y)

    @xxy.setter
    def xxy(self, value):
        raise RuntimeError(
            "Elements in this vector 'xxy' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def xxz(self):
        return Vector3(self.x, self.x, self.z)

    @xxz.setter
    def xxz(self, value):
        raise RuntimeError(
            "Elements in this vector 'xxz' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def xyx(self):
        return Vector3(self.x, self.y, self.x)

    @xyx.setter
    def xyx(self, value):
        raise RuntimeError(
            "Elements in this vector 'xyx' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def xyy(self):
        return Vector3(self.x, self.y, self.y)

    @xyy.setter
    def xyy(self, value):
        raise RuntimeError(
            "Elements in this vector 'xyy' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def xyz(self):
        return Vector3(self.x, self.y, self.z)

    @xyz.setter
    def xyz(self, value):
        if isinstance(value, Vector3):
            self.x = value.x
            self.y = value.y
            self.z = value.z
        else:
            self.x = value
            self.y = value
            self.z = value

    @property
    def xzx(self):
        return Vector3(self.x, self.z, self.x)

    @xzx.setter
    def xzx(self, value):
        raise RuntimeError(
            "Elements in this vector 'xzx' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def xzy(self):
        return Vector3(self.x, self.z, self.y)

    @xzy.setter
    def xzy(self, value):
        if isinstance(value, Vector3):
            self.x = value.x
            self.z = value.y
            self.y = value.z
        else:
            self.x = value
            self.z = value
            self.y = value

    @property
    def xzz(self):
        return Vector3(self.x, self.z, self.z)

    @xzz.setter
    def xzz(self, value):
        raise RuntimeError(
            "Elements in this vector 'xzz' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def yxx(self):
        return Vector3(self.y, self.x, self.x)

    @yxx.setter
    def yxx(self, value):
        raise RuntimeError(
            "Elements in this vector 'yxx' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def yxy(self):
        return Vector3(self.y, self.x, self.y)

    @yxy.setter
    def yxy(self, value):
        raise RuntimeError(
            "Elements in this vector 'yxy' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def yxz(self):
        return Vector3(self.y, self.x, self.z)

    @yxz.setter
    def yxz(self, value):
        if isinstance(value, Vector3):
            self.y = value.x
            self.x = value.y
            self.z = value.z
        else:
            self.y = value
            self.x = value
            self.z = value

    @property
    def yyx(self):
        return Vector3(self.y, self.y, self.x)

    @yyx.setter
    def yyx(self, value):
        raise RuntimeError(
            "Elements in this vector 'yyx' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def yyy(self):
        return Vector3(self.y, self.y, self.y)

    @yyy.setter
    def yyy(self, value):
        raise RuntimeError(
            "Elements in this vector 'yyy' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def yyz(self):
        return Vector3(self.y, self.y, self.z)

    @yyz.setter
    def yyz(self, value):
        raise RuntimeError(
            "Elements in this vector 'yyz' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def yzx(self):
        return Vector3(self.y, self.z, self.x)

    @yzx.setter
    def yzx(self, value):
        if isinstance(value, Vector3):
            self.y = value.x
            self.z = value.y
            self.x = value.z
        else:
            self.y = value
            self.z = value
            self.x = value

    @property
    def yzy(self):
        return Vector3(self.y, self.z, self.y)

    @yzy.setter
    def yzy(self, value):
        raise RuntimeError(
            "Elements in this vector 'yzy' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def yzz(self):
        return Vector3(self.y, self.z, self.z)

    @yzz.setter
    def yzz(self, value):
        raise RuntimeError(
            "Elements in this vector 'yzz' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def zxx(self):
        return Vector3(self.z, self.x, self.x)

    @zxx.setter
    def zxx(self, value):
        raise RuntimeError(
            "Elements in this vector 'zxx' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def zxy(self):
        return Vector3(self.z, self.x, self.y)

    @zxy.setter
    def zxy(self, value):
        if isinstance(value, Vector3):
            self.z = value.x
            self.x = value.y
            self.y = value.z
        else:
            self.z = value
            self.x = value
            self.y = value

    @property
    def zxz(self):
        return Vector3(self.z, self.x, self.z)

    @zxz.setter
    def zxz(self, value):
        raise RuntimeError(
            "Elements in this vector 'zxz' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def zyx(self):
        return Vector3(self.z, self.y, self.x)

    @zyx.setter
    def zyx(self, value):
        if isinstance(value, Vector3):
            self.z = value.x
            self.y = value.y
            self.x = value.z
        else:
            self.z = value
            self.y = value
            self.x = value

    @property
    def zyy(self):
        return Vector3(self.z, self.y, self.y)

    @zyy.setter
    def zyy(self, value):
        raise RuntimeError(
            "Elements in this vector 'zyy' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def zyz(self):
        return Vector3(self.z, self.y, self.z)

    @zyz.setter
    def zyz(self, value):
        raise RuntimeError(
            "Elements in this vector 'zyz' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def zzx(self):
        return Vector3(self.z, self.z, self.x)

    @zzx.setter
    def zzx(self, value):
        raise RuntimeError(
            "Elements in this vector 'zzx' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def zzy(self):
        return Vector3(self.z, self.z, self.y)

    @zzy.setter
    def zzy(self, value):
        raise RuntimeError(
            "Elements in this vector 'zzy' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def zzz(self):
        return Vector3(self.z, self.z, self.z)

    @zzz.setter
    def zzz(self, value):
        raise RuntimeError(
            "Elements in this vector 'zzz' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def xx(self):
        return Vector2(self.x, self.x)

    @xx.setter
    def xx(self, value):
        raise RuntimeError(
            "Elements in this vector 'xx' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def xy(self):
        return Vector2(self.x, self.y)

    @xy.setter
    def xy(self, value):
        if isinstance(value, Vector2):
            self.x = value.x
            self.y = value.y
        else:
            self.x = value
            self.y = value

    @property
    def xz(self):
        return Vector2(self.x, self.z)

    @xz.setter
    def xz(self, value):
        if isinstance(value, Vector2):
            self.x = value.x
            self.z = value.y
        else:
            self.x = value
            self.z = value

    @property
    def yx(self):
        return Vector2(self.y, self.x)

    @yx.setter
    def yx(self, value):
        if isinstance(value, Vector2):
            self.y = value.x
            self.x = value.y
        else:
            self.y = value
            self.x = value

    @property
    def yy(self):
        return Vector2(self.y, self.y)

    @yy.setter
    def yy(self, value):
        raise RuntimeError(
            "Elements in this vector 'yy' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def yz(self):
        return Vector2(self.y, self.z)

    @yz.setter
    def yz(self, value):
        if isinstance(value, Vector2):
            self.y = value.x
            self.z = value.y
        else:
            self.y = value
            self.z = value

    @property
    def zx(self):
        return Vector2(self.z, self.x)

    @zx.setter
    def zx(self, value):
        if isinstance(value, Vector2):
            self.z = value.x
            self.x = value.y
        else:
            self.z = value
            self.x = value

    @property
    def zy(self):
        return Vector2(self.z, self.y)

    @zy.setter
    def zy(self, value):
        if isinstance(value, Vector2):
            self.z = value.x
            self.y = value.y
        else:
            self.z = value
            self.y = value

    @property
    def zz(self):
        return Vector2(self.z, self.z)

    @zz.setter
    def zz(self, value):
        raise RuntimeError(
            "Elements in this vector 'zz' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    def __eq__(self, other):
        if isinstance(other, Vector3):
            return self.x == other.x and self.y == other.y and self.z == other.z
        else:
            return NotImplemented

    def __ne__(self, other):
        if isinstance(other, Vector3):
            return self.x != other.x or self.y != other.y or self.z != other.z
        else:
            return NotImplemented

    def __matmul__(self, other):
        return NotImplemented

    """Arithmetic operations are performed component-wise
    """

    def __or__(self, other):
        if isinstance(other, Vector3):
            x = self.x | other.x
            y = self.y | other.y
            z = self.z | other.z
        else:
            x = self.x | other
            y = self.y | other
            z = self.z | other
        return Vector3(x, y, z)

    def __ror__(self, other):
        x = other | self.x
        y = other | self.y
        z = other | self.z
        return Vector3(x, y, z)

    def __ior__(self, other):
        if self.x is self.y or self.x is self.z or self.y is self.z:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector3):
            self.x |= other.x
            self.y |= other.y
            self.z |= other.z
        else:
            self.x |= other
            self.y |= other
            self.z |= other
        return self

    def __mul__(self, other):
        if isinstance(other, Vector3):
            x = self.x * other.x
            y = self.y * other.y
            z = self.z * other.z
        else:
            x = self.x * other
            y = self.y * other
            z = self.z * other
        return Vector3(x, y, z)

    def __rmul__(self, other):
        x = other * self.x
        y = other * self.y
        z = other * self.z
        return Vector3(x, y, z)

    def __imul__(self, other):
        if self.x is self.y or self.x is self.z or self.y is self.z:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector3):
            self.x *= other.x
            self.y *= other.y
            self.z *= other.z
        else:
            self.x *= other
            self.y *= other
            self.z *= other
        return self

    def __pow__(self, other):
        if isinstance(other, Vector3):
            x = self.x**other.x
            y = self.y**other.y
            z = self.z**other.z
        else:
            x = self.x**other
            y = self.y**other
            z = self.z**other
        return Vector3(x, y, z)

    def __rpow__(self, other):
        x = other**self.x
        y = other**self.y
        z = other**self.z
        return Vector3(x, y, z)

    def __ipow__(self, other):
        if self.x is self.y or self.x is self.z or self.y is self.z:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector3):
            self.x **= other.x
            self.y **= other.y
            self.z **= other.z
        else:
            self.x **= other
            self.y **= other
            self.z **= other
        return self

    def __xor__(self, other):
        if isinstance(other, Vector3):
            x = self.x ^ other.x
            y = self.y ^ other.y
            z = self.z ^ other.z
        else:
            x = self.x ^ other
            y = self.y ^ other
            z = self.z ^ other
        return Vector3(x, y, z)

    def __rxor__(self, other):
        x = other ^ self.x
        y = other ^ self.y
        z = other ^ self.z
        return Vector3(x, y, z)

    def __ixor__(self, other):
        if self.x is self.y or self.x is self.z or self.y is self.z:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector3):
            self.x ^= other.x
            self.y ^= other.y
            self.z ^= other.z
        else:
            self.x ^= other
            self.y ^= other
            self.z ^= other
        return self

    def __rshift__(self, other):
        if isinstance(other, Vector3):
            x = self.x >> other.x
            y = self.y >> other.y
            z = self.z >> other.z
        else:
            x = self.x >> other
            y = self.y >> other
            z = self.z >> other
        return Vector3(x, y, z)

    def __rrshift__(self, other):
        x = other >> self.x
        y = other >> self.y
        z = other >> self.z
        return Vector3(x, y, z)

    def __irshift__(self, other):
        if self.x is self.y or self.x is self.z or self.y is self.z:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector3):
            self.x >>= other.x
            self.y >>= other.y
            self.z >>= other.z
        else:
            self.x >>= other
            self.y >>= other
            self.z >>= other
        return self

    def __lshift__(self, other):
        if isinstance(other, Vector3):
            x = self.x << other.x
            y = self.y << other.y
            z = self.z << other.z
        else:
            x = self.x << other
            y = self.y << other
            z = self.z << other
        return Vector3(x, y, z)

    def __rlshift__(self, other):
        x = other << self.x
        y = other << self.y
        z = other << self.z
        return Vector3(x, y, z)

    def __ilshift__(self, other):
        if self.x is self.y or self.x is self.z or self.y is self.z:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector3):
            self.x <<= other.x
            self.y <<= other.y
            self.z <<= other.z
        else:
            self.x <<= other
            self.y <<= other
            self.z <<= other
        return self

    def __truediv__(self, other):
        if isinstance(other, Vector3):
            x = self.x / other.x
            y = self.y / other.y
            z = self.z / other.z
        else:
            x = self.x / other
            y = self.y / other
            z = self.z / other
        return Vector3(x, y, z)

    def __rtruediv__(self, other):
        x = other / self.x
        y = other / self.y
        z = other / self.z
        return Vector3(x, y, z)

    def __itruediv__(self, other):
        if self.x is self.y or self.x is self.z or self.y is self.z:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector3):
            self.x /= other.x
            self.y /= other.y
            self.z /= other.z
        else:
            self.x /= other
            self.y /= other
            self.z /= other
        return self

    def __sub__(self, other):
        if isinstance(other, Vector3):
            x = self.x - other.x
            y = self.y - other.y
            z = self.z - other.z
        else:
            x = self.x - other
            y = self.y - other
            z = self.z - other
        return Vector3(x, y, z)

    def __rsub__(self, other):
        x = other - self.x
        y = other - self.y
        z = other - self.z
        return Vector3(x, y, z)

    def __isub__(self, other):
        if self.x is self.y or self.x is self.z or self.y is self.z:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector3):
            self.x -= other.x
            self.y -= other.y
            self.z -= other.z
        else:
            self.x -= other
            self.y -= other
            self.z -= other
        return self

    def __and__(self, other):
        if isinstance(other, Vector3):
            x = self.x & other.x
            y = self.y & other.y
            z = self.z & other.z
        else:
            x = self.x & other
            y = self.y & other
            z = self.z & other
        return Vector3(x, y, z)

    def __rand__(self, other):
        x = other & self.x
        y = other & self.y
        z = other & self.z
        return Vector3(x, y, z)

    def __iand__(self, other):
        if self.x is self.y or self.x is self.z or self.y is self.z:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector3):
            self.x &= other.x
            self.y &= other.y
            self.z &= other.z
        else:
            self.x &= other
            self.y &= other
            self.z &= other
        return self

    def __mod__(self, other):
        if isinstance(other, Vector3):
            x = self.x % other.x
            y = self.y % other.y
            z = self.z % other.z
        else:
            x = self.x % other
            y = self.y % other
            z = self.z % other
        return Vector3(x, y, z)

    def __rmod__(self, other):
        x = other % self.x
        y = other % self.y
        z = other % self.z
        return Vector3(x, y, z)

    def __imod__(self, other):
        if self.x is self.y or self.x is self.z or self.y is self.z:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector3):
            self.x %= other.x
            self.y %= other.y
            self.z %= other.z
        else:
            self.x %= other
            self.y %= other
            self.z %= other
        return self

    def __add__(self, other):
        if isinstance(other, Vector3):
            x = self.x + other.x
            y = self.y + other.y
            z = self.z + other.z
        else:
            x = self.x + other
            y = self.y + other
            z = self.z + other
        return Vector3(x, y, z)

    def __radd__(self, other):
        x = other + self.x
        y = other + self.y
        z = other + self.z
        return Vector3(x, y, z)

    def __iadd__(self, other):
        if self.x is self.y or self.x is self.z or self.y is self.z:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector3):
            self.x += other.x
            self.y += other.y
            self.z += other.z
        else:
            self.x += other
            self.y += other
            self.z += other
        return self

    def __floordiv__(self, other):
        if isinstance(other, Vector3):
            x = self.x // other.x
            y = self.y // other.y
            z = self.z // other.z
        else:
            x = self.x // other
            y = self.y // other
            z = self.z // other
        return Vector3(x, y, z)

    def __rfloordiv__(self, other):
        x = other // self.x
        y = other // self.y
        z = other // self.z
        return Vector3(x, y, z)

    def __ifloordiv__(self, other):
        if self.x is self.y or self.x is self.z or self.y is self.z:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector3):
            self.x //= other.x
            self.y //= other.y
            self.z //= other.z
        else:
            self.x //= other
            self.y //= other
            self.z //= other
        return self

    def __divmod__(self, other):
        if isinstance(other, Vector3):
            x = divmod(self.x, other.x)
            y = divmod(self.y, other.y)
            z = divmod(self.z, other.z)
        else:
            x = divmod(self.x, other)
            y = divmod(self.y, other)
            z = divmod(self.z, other)
        return Vector3(x, y, z)

    def __rdivmod__(self, other):
        x = divmod(other, self.x)
        y = divmod(other, self.y)
        z = divmod(other, self.z)
        return Vector3(x, y, z)

    def __neg__(self):
        return Vector3(-self.x, -self.y, -self.z)

    def __invert__(self):
        return Vector3(~self.x, ~self.y, ~self.z)

    def __pos__(self):
        return Vector3(+self.x, +self.y, +self.z)

    def __abs__(self):
        return Vector3(abs(self.x), abs(self.y), abs(self.z))

    def __round__(self, n=0):
        return Vector3(round(self.x, n), round(self.y, n), round(self.z, n))
Ejemplo n.º 8
0
class Vector2:
    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x = Coord(value)

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, value):
        self._y = Coord(value)

    def __init__(self, x=0, y=None, by_ref=False):
        if y is None:
            if isinstance(x, Coord):
                self.x = x.copy()
                self.y = x.copy()
            else:
                self.x = Coord(x)
                self.y = Coord(x)
            return
        if not by_ref:
            self.x = x
            self.y = y
        if isinstance(x, Coord):
            self._x = x
        else:
            self.x = x
        if isinstance(y, Coord):
            self._y = y
        else:
            self.y = y

    def dot(self, vec):
        if not isinstance(vec, Vector2):
            raise TypeError("Vector sizes must match")
        return self.x * vec.x + self.y * vec.y

    def copy(self):
        return Vector2(self.x.copy(), self.y.copy())

    def __len__(self):
        return 2

    def __iter__(self):
        yield self.x
        yield self.y

    def __getitem__(self, key):
        keys = "xy"
        if isinstance(key, int):
            key = keys[key]
        if key == "x":
            return self.x
        elif key == "y":
            return self.y
        else:
            raise IndexError("Vector2 does not contain {}".format(key))

    def __setitem__(self, key, value):
        keys = "xy"
        if isinstance(key, int):
            key = keys[key]
        if key == "x":
            self.x = value
        elif key == "y":
            self.y = value
        else:
            raise IndexError("Vector2 does not contain {}".format(key))

    def __repr__(self):
        return "Vector2('{}','{}')".format(str(self.x), str(self.y))

    def __str__(self):
        return "({},{})".format(str(self.x), str(self.y))

    def simple_str(self):
        return "{} {}".format(str(self.x), str(self.y))

    @property
    def xxx(self):
        return Vector2(self.x, self.x)

    @property
    def xxy(self):
        return Vector2(self.x, self.x)

    @property
    def xyx(self):
        return Vector2(self.x, self.y)

    @property
    def xyy(self):
        return Vector2(self.x, self.y)

    @property
    def yxx(self):
        return Vector2(self.y, self.x)

    @property
    def yxy(self):
        return Vector2(self.y, self.x)

    @property
    def yyx(self):
        return Vector2(self.y, self.y)

    @property
    def yyy(self):
        return Vector2(self.y, self.y)

    @property
    def xx(self):
        return Vector2(self.x, self.x)

    @xx.setter
    def xxy(self, value):
        raise RuntimeError(
            "Elements in this vector 'xx' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    @property
    def xy(self):
        return Vector2(self.x, self.y)

    @xy.setter
    def xy(self, value):
        if isinstance(value, Vector2):
            self.x = value.x
            self.y = value.y
        else:
            self.x = value
            self.y = value

    @property
    def yx(self):
        return Vector2(self.y, self.x)

    @yx.setter
    def yx(self, value):
        if isinstance(value, Vector2):
            self.y = value.x
            self.x = value.y
        else:
            self.y = value
            self.x = value

    @property
    def yy(self):
        return Vector2(self.y, self.y)

    @yy.setter
    def yyy(self, value):
        raise RuntimeError(
            "Elements in this vector 'yy' refer to the same object, which makes assignment undefined"
        )
        return NotImplemented

    def __eq__(self, other):
        if isinstance(other, Vector2):
            return self.x == other.x and self.y == other.y
        else:
            return NotImplemented

    def __ne__(self, other):
        if isinstance(other, Vector2):
            return self.x != other.x or self.y != other.y
        else:
            return NotImplemented

    def __matmul__(self, other):
        return NotImplemented

    """Arithmetic operations are performed component-wise
    """

    def __or__(self, other):
        if isinstance(other, Vector2):
            x = self.x | other.x
            y = self.y | other.y
        else:
            x = self.x | other
            y = self.y | other
        return Vector2(x, y)

    def __ror__(self, other):
        x = other | self.x
        y = other | self.y
        return Vector2(x, y)

    def __ior__(self, other):
        if self.x is self.y:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector2):
            self.x |= other.x
            self.y |= other.y
        else:
            self.x |= other
            self.y |= other
        return self

    def __mul__(self, other):
        if isinstance(other, Vector2):
            x = self.x * other.x
            y = self.y * other.y
        else:
            x = self.x * other
            y = self.y * other
        return Vector2(x, y)

    def __rmul__(self, other):
        x = other * self.x
        y = other * self.y
        return Vector2(x, y)

    def __imul__(self, other):
        if self.x is self.y:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector2):
            self.x *= other.x
            self.y *= other.y
        else:
            self.x *= other
            self.y *= other
        return self

    def __pow__(self, other):
        if isinstance(other, Vector2):
            x = self.x**other.x
            y = self.y**other.y
        else:
            x = self.x**other
            y = self.y**other
        return Vector2(x, y)

    def __rpow__(self, other):
        x = other**self.x
        y = other**self.y
        return Vector2(x, y)

    def __ipow__(self, other):
        if self.x is self.y:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector2):
            self.x **= other.x
            self.y **= other.y
        else:
            self.x **= other
            self.y **= other
        return self

    def __xor__(self, other):
        if isinstance(other, Vector2):
            x = self.x ^ other.x
            y = self.y ^ other.y
        else:
            x = self.x ^ other
            y = self.y ^ other
        return Vector2(x, y)

    def __rxor__(self, other):
        x = other ^ self.x
        y = other ^ self.y
        return Vector2(x, y)

    def __ixor__(self, other):
        if self.x is self.y:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector2):
            self.x ^= other.x
            self.y ^= other.y
        else:
            self.x ^= other
            self.y ^= other
        return self

    def __rshift__(self, other):
        if isinstance(other, Vector2):
            x = self.x >> other.x
            y = self.y >> other.y
        else:
            x = self.x >> other
            y = self.y >> other
        return Vector2(x, y)

    def __rrshift__(self, other):
        x = other >> self.x
        y = other >> self.y
        return Vector2(x, y)

    def __irshift__(self, other):
        if self.x is self.y:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector2):
            self.x >>= other.x
            self.y >>= other.y
        else:
            self.x >>= other
            self.y >>= other
        return self

    def __lshift__(self, other):
        if isinstance(other, Vector2):
            x = self.x << other.x
            y = self.y << other.y
        else:
            x = self.x << other
            y = self.y << other
        return Vector2(x, y)

    def __rlshift__(self, other):
        x = other << self.x
        y = other << self.y
        return Vector2(x, y)

    def __ilshift__(self, other):
        if self.x is self.y:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector2):
            self.x <<= other.x
            self.y <<= other.y
        else:
            self.x <<= other
            self.y <<= other
        return self

    def __truediv__(self, other):
        if isinstance(other, Vector2):
            x = self.x / other.x
            y = self.y / other.y
        else:
            x = self.x / other
            y = self.y / other
        return Vector2(x, y)

    def __rtruediv__(self, other):
        x = other / self.x
        y = other / self.y
        return Vector2(x, y)

    def __itruediv__(self, other):
        if self.x is self.y:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector2):
            self.x /= other.x
            self.y /= other.y
        else:
            self.x /= other
            self.y /= other
        return self

    def __sub__(self, other):
        if isinstance(other, Vector2):
            x = self.x - other.x
            y = self.y - other.y
        else:
            x = self.x - other
            y = self.y - other
        return Vector2(x, y)

    def __rsub__(self, other):
        x = other - self.x
        y = other - self.y
        return Vector2(x, y)

    def __isub__(self, other):
        if self.x is self.y:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector2):
            self.x -= other.x
            self.y -= other.y
        else:
            self.x -= other
            self.y -= other
        return self

    def __and__(self, other):
        if isinstance(other, Vector2):
            x = self.x & other.x
            y = self.y & other.y
        else:
            x = self.x & other
            y = self.y & other
        return Vector2(x, y)

    def __rand__(self, other):
        x = other & self.x
        y = other & self.y
        return Vector2(x, y)

    def __iand__(self, other):
        if self.x is self.y:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector2):
            self.x &= other.x
            self.y &= other.y
        else:
            self.x &= other
            self.y &= other
        return self

    def __mod__(self, other):
        if isinstance(other, Vector2):
            x = self.x % other.x
            y = self.y % other.y
        else:
            x = self.x % other
            y = self.y % other
        return Vector2(x, y)

    def __rmod__(self, other):
        x = other % self.x
        y = other % self.y
        return Vector2(x, y)

    def __imod__(self, other):
        if self.x is self.y:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector2):
            self.x %= other.x
            self.y %= other.y
        else:
            self.x %= other
            self.y %= other
        return self

    def __add__(self, other):
        if isinstance(other, Vector2):
            x = self.x + other.x
            y = self.y + other.y
        else:
            x = self.x + other
            y = self.y + other
        return Vector2(x, y)

    def __radd__(self, other):
        x = other + self.x
        y = other + self.y
        return Vector2(x, y)

    def __iadd__(self, other):
        if self.x is self.y:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector2):
            self.x += other.x
            self.y += other.y
        else:
            self.x += other
            self.y += other
        return self

    def __floordiv__(self, other):
        if isinstance(other, Vector2):
            x = self.x // other.x
            y = self.y // other.y
        else:
            x = self.x // other
            y = self.y // other
        return Vector2(x, y)

    def __rfloordiv__(self, other):
        x = other // self.x
        y = other // self.y
        return Vector2(x, y)

    def __ifloordiv__(self, other):
        if self.x is self.y:
            raise RuntimeError(
                "Elements in this vector refer to the same object, which makes assignment undefined"
            )
            return NotImplemented
        if isinstance(other, Vector2):
            self.x //= other.x
            self.y //= other.y
        else:
            self.x //= other
            self.y //= other
        return self

    def __divmod__(self, other):
        if isinstance(other, Vector2):
            x = divmod(self.x, other.x)
            y = divmod(self.y, other.y)
        else:
            x = divmod(self.x, other)
            y = divmod(self.y, other)
        return Vector2(x, y)

    def __rdivmod__(self, other):
        x = divmod(other, self.x)
        y = divmod(other, self.y)
        return Vector2(x, y)

    def __neg__(self):
        return Vector2(-self.x, -self.y)

    def __invert__(self):
        return Vector2(~self.x, ~self.y)

    def __pos__(self):
        return Vector2(+self.x, +self.y)

    def __abs__(self):
        return Vector2(abs(self.x), abs(self.y))

    def __round__(self, n=0):
        return Vector2(round(self.x, n), round(self.y, n))

    def rotated(self, angle, point_vec=None, radians=True):
        if not radians:
            angle = math.radians(angle)
        angle = Coord(angle).value
        if point_vec is None:
            point_vec = Vector2()
        assert isinstance(point_vec, Vector2), "point_vec must be a Vector2"
        result = self.copy()
        result -= point_vec
        new_x = result.x * math.cos(angle) + result.y * math.sin(angle)
        new_y = result.x * -math.sin(angle) + result.y * math.cos(angle)
        result.x, result.y = new_x, new_y
        result += point_vec
        result.x._prefix = self.x._prefix
        result.y._prefix = self.y._prefix
        return result

    def rotate(self, angle, point_vec=None, radians=True):
        rotated_vec = self.rotated(angle, point_vec, radians)
        self.x._set_value(rotated_vec.x)
        self.y._set_value(rotated_vec.y)