U
    Pe"(                     @   s$   d Z dZddlZG dd deZdS )aY  Vector
======

The :class:`Vector` represents a 2D vector (x, y).
Our implementation is built on top of a Python list.

 An example of constructing a Vector::

    >>> # Construct a point at 82,34
    >>> v = Vector(82, 34)
    >>> v[0]
    82
    >>> v.x
    82
    >>> v[1]
    34
    >>> v.y
    34

    >>> # Construct by giving a list of 2 values
    >>> pos = (93, 45)
    >>> v = Vector(pos)
    >>> v[0]
    93
    >>> v.x
    93
    >>> v[1]
    45
    >>> v.y
    45


Optimized usage
---------------

Most of the time, you can use a list for arguments instead of using a
Vector. For example, if you want to calculate the distance between 2
points::

    a = (10, 10)
    b = (87, 34)

    # optimized method
    print('distance between a and b:', Vector(a).distance(b))

    # non-optimized method
    va = Vector(a)
    vb = Vector(b)
    print('distance between a and b:', va.distance(vb))


Vector operators
----------------

The :class:`Vector` supports some numeric operators such as +, -, /::

    >>> Vector(1, 1) + Vector(9, 5)
    [10, 6]

    >>> Vector(9, 5) - Vector(5, 5)
    [4, 0]

    >>> Vector(10, 10) / Vector(2., 4.)
    [5.0, 2.5]

    >>> Vector(10, 10) / 5.
    [2.0, 2.0]


You can also use in-place operators::

    >>> v = Vector(1, 1)
    >>> v += 2
    >>> v
    [3, 3]
    >>> v *= 5
    [15, 15]
    >>> v /= 2.
    [7.5, 7.5]

Vector    Nc                       s,  e Zd ZdZ fddZdd Zdd ZeeeZdd	 Z	d
d Z
ee	e
Z fddZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Z d6d7 Z!e"d8d9 Z#e"d:d; Z$e"d<d= Z%  Z&S )>r   zAVector class. See module documentation for more information.
    c                    sL   t |dkr"tt| |d  n&t |dkr@tt| | ntdd S )N   r      zInvalid vector)lensuperr   __init__	Exception)selflargs	__class__ //tmp/pip-unpacked-wheel-xzebddm3/kivy/vector.pyr   \   s
    zVector.__init__c                 C   s   | d S Nr   r   r
   r   r   r   _get_xd   s    zVector._get_xc                 C   s   || d< d S r   r   )r
   xr   r   r   _set_xg   s    zVector._set_xc                 C   s   | d S Nr   r   r   r   r   r   _get_yt   s    zVector._get_yc                 C   s   || d< d S r   r   )r
   yr   r   r   _set_yw   s    zVector._set_yc                    s:   zt tt | ||W S  tk
r4   tdY nX d S )Nzvector::FAILURE in __getslice__)r   r   __getslice__r	   	TypeError)r
   ijr   r   r   r      s    zVector.__getslice__c                 C   s   t ttdd | |S )Nc                 S   s   | | S Nr   r   r   r   r   r   <lambda>       z Vector.__add__.<locals>.<lambda>r   listmapr
   valr   r   r   __add__   s    zVector.__add__c                 C   sR   t |ttfkr.|  j|7  _|  j|7  _n |  j|j7  _|  j|j7  _| S r   typeintfloatr   r   r$   r   r   r   __iadd__   s    zVector.__iadd__c                 C   s   t dd | D S )Nc                 S   s   g | ]
}| qS r   r   .0r   r   r   r   
<listcomp>   s     z"Vector.__neg__.<locals>.<listcomp>r   r   r   r   r   __neg__   s    zVector.__neg__c                 C   s   t ttdd | |S )Nc                 S   s   | | S r   r   r   r   r   r   r      r    z Vector.__sub__.<locals>.<lambda>r!   r$   r   r   r   __sub__   s    zVector.__sub__c                 C   sR   t |ttfkr.|  j|8  _|  j|8  _n |  j|j8  _|  j|j8  _| S r   r'   r$   r   r   r   __isub__   s    zVector.__isub__c                    sJ   zt ttdd |  W S  tk
rD   t  fdd| D  Y S X d S )Nc                 S   s   | | S r   r   r   r   r   r   r      r    z Vector.__mul__.<locals>.<lambda>c                    s   g | ]}|  qS r   r   r,   r%   r   r   r.      s     z"Vector.__mul__.<locals>.<listcomp>r   r"   r#   r	   r$   r   r2   r   __mul__   s    zVector.__mul__c                 C   sR   t |ttfkr.|  j|9  _|  j|9  _n |  j|j9  _|  j|j9  _| S r   r'   r$   r   r   r   __imul__   s    zVector.__imul__c                 C   s   | | S r   r   r$   r   r   r   __rmul__   s    zVector.__rmul__c                    sJ   zt ttdd |  W S  tk
rD   t  fdd| D  Y S X d S )Nc                 S   s   | | S r   r   r   r   r   r   r      r    z$Vector.__truediv__.<locals>.<lambda>c                    s   g | ]}|  qS r   r   r,   r2   r   r   r.      s     z&Vector.__truediv__.<locals>.<listcomp>r3   r$   r   r2   r   __truediv__   s    zVector.__truediv__c                    sJ   zt ttdd |  W S  tk
rD   t  fdd| D  Y S X d S )Nc                 S   s   | | S r   r   r   r   r   r   r      r    z Vector.__div__.<locals>.<lambda>c                    s   g | ]}|  qS r   r   r,   r2   r   r   r.      s     z"Vector.__div__.<locals>.<listcomp>r3   r$   r   r2   r   __div__   s    zVector.__div__c                 C   s6   zt | |  W S  tk
r0   t |||   Y S X d S r   r   r	   r$   r   r   r   __rtruediv__   s    zVector.__rtruediv__c                 C   s6   zt | |  W S  tk
r0   t |||   Y S X d S r   r9   r$   r   r   r   __rdiv__   s    zVector.__rdiv__c                 C   sR   t |ttfkr.|  j|  _|  j|  _n |  j|j  _|  j|j  _| S r   r'   r$   r   r   r   __idiv__   s    zVector.__idiv__c                 C   s   t | d d | d d  S )zReturns the length of a vector.

        >>> Vector(10, 10).length()
        14.142135623730951
        >>> pos = (10, 10)
        >>> Vector(pos).length()
        14.142135623730951

        r   r   r   mathsqrtr   r   r   r   length   s    
zVector.lengthc                 C   s   | d d | d d  S )zReturns the length of a vector squared.

        >>> Vector(10, 10).length2()
        200
        >>> pos = (10, 10)
        >>> Vector(pos).length2()
        200

        r   r   r   r   r   r   r   r   length2   s    
zVector.length2c                 C   s.   t | d |d  d | d |d  d  S )zReturns the distance between two points.

        >>> Vector(10, 10).distance((5, 10))
        5.
        >>> a = (90, 33)
        >>> b = (76, 34)
        >>> Vector(a).distance(b)
        14.035668847618199

        r   r   r   r=   r
   tor   r   r   distance   s    zVector.distancec                 C   s(   | d |d  d | d |d  d  S )ztReturns the distance between two points squared.

        >>> Vector(10, 10).distance2((5, 10))
        25

        r   r   r   r   rB   r   r   r   	distance2   s    zVector.distance2c                 C   s.   | d dkr"| d dkr"t ddS | |   S )zReturns a new vector that has the same direction as vec,
        but has a length of one.

        >>> v = Vector(88, 33).normalize()
        >>> v
        [0.93632917756904444, 0.3511234415883917]
        >>> v.length()
        1.0

        r   g        r   )r   r@   r   r   r   r   	normalize	  s    
zVector.normalizec                 C   s    | d |d  | d |d   S )z_Computes the dot product of a and b.

        >>> Vector(2, 4).dot((2, 2))
        12

        r   r   r   )r
   ar   r   r   dot  s    z
Vector.dotc                 C   sT   dt j  t | d |d  | d |d   | d |d  | d |d    }|S )zComputes the angle between a and b, and returns the angle in
        degrees.

        >>> Vector(100, 0).angle((0, 100))
        -90.0
        >>> Vector(87, 23).angle((-77, 10))
        -157.7920283010705

           r   r   )r>   piatan2)r
   rG   angler   r   r   rL   !  s
    
zVector.anglec                 C   sT   t |}t| d t | | d t |  | d t | | d t |  S )zRotate the vector with an angle in degrees.

        >>> v = Vector(100, 0)
        >>> v.rotate(45)
        [70.71067811865476, 70.71067811865474]

        r   r   )r>   radiansr   cossin)r
   rL   r   r   r   rotate0  s
    
""zVector.rotatec                 C   s   t | d t |d t |d t |d f\}}}}t | d t |d t |d t |d f\}}	}
}||	 ||  }|| |
|  }|| |
|  ||	 ||   }|dkrdS |||  || |  | }||
|  ||	 |  | }t||S )a  
        Finds the intersection point between the lines (1)v1->v2 and (2)v3->v4
        and returns it as a vector object.

        >>> a = (98, 28)
        >>> b = (72, 33)
        >>> c = (10, -5)
        >>> d = (20, 88)
        >>> Vector.line_intersection(a, b, c, d)
        [15.25931928687196, 43.911669367909241]

        .. warning::

            This is a line intersection method, not a segment intersection.

        For math see: http://en.wikipedia.org/wiki/Line-line_intersection
        r   r   Nr*   r   )v1v2v3v4x1x2x3x4y1y2y3y4uvdenompxpyr   r   r   line_intersection=  s    44 zVector.line_intersectionc                 C   s  t | d t |d t |d t |d f\}}}}t | d t |d t |d t |d f\}}	}
}||	 ||  }|| |
|  }|| |
|  ||	 ||   }|dkrdS |||  || |  | }||
|  ||	 |  | }||  ko|kn  p(||  ko|kn  p(||k}||  ko>|	kn  ph|	|  koZ|kn  ph||	k}||  ko~|kn  p||  ko|kn  p||k}|
|  ko|kn  p||  ko|
kn  p|
|k}|r|r|r|rt||S dS dS )a  
        Finds the intersection point between segments (1)v1->v2 and (2)v3->v4
        and returns it as a vector object.

        >>> a = (98, 28)
        >>> b = (72, 33)
        >>> c = (10, -5)
        >>> d = (20, 88)
        >>> Vector.segment_intersection(a, b, c, d)
        None

        >>> a = (0, 0)
        >>> b = (10, 10)
        >>> c = (0, 10)
        >>> d = (10, 0)
        >>> Vector.segment_intersection(a, b, c, d)
        [5, 5]
        r   r   NrQ   )rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   Zc1c2c3Zc4r   r   r   segment_intersection_  s     44 >@@@
zVector.segment_intersectionc                 C   s   | d |d kr | d |d ks@| d |d ko~| d |d ko~| d |d kr`| d |d kp~| d |d ko~| d |d kS )a  Return True if `point` is in the bounding box defined by `a`
        and `b`.

        >>> bmin = (0, 0)
        >>> bmax = (100, 100)
        >>> Vector.in_bbox((50, 50), bmin, bmax)
        True
        >>> Vector.in_bbox((647, -10), bmin, bmax)
        False

        r   r   r   )ZpointrG   br   r   r   in_bbox  s      zVector.in_bbox)'__name__
__module____qualname____doc__r   r   r   propertyr   r   r   r   r   r&   r+   r/   r0   r1   r4   r5   r6   r7   r8   r:   r;   r<   r@   rA   rD   rE   rF   rH   rL   rP   staticmethodrc   rf   rh   __classcell__r   r   r   r   r   X   sH   


						
!
,r   )rl   __all__r>   r"   r   r   r   r   r   <module>   s   R