o
    oi*                     @  s   d dl mZ d dlZd dlmZ d dlmZmZ d dlm	Z	m
Z
 g dZd(ddZd)ddZd*ddZd+ddZd,d-ddZd.d/d!d"Zd.d0d#d$Zd1d2d&d'ZeZdS )3    )annotationsN)Tensor)KORNIA_CHECK_IS_TENSORKORNIA_CHECK_SHAPE)convert_points_from_homogeneousconvert_points_to_homogeneous)	batched_dot_productbatched_squared_normcompose_transformationseuclidean_distanceinverse_transformationpoint_line_distancerelative_transformationsquared_normtransform_pointstrans_01r   trans_12returnc           	      C  sP  t |  t | |  dv r| jdd dkstd| j | dv r.|jdd dks6td|j |  | krLtd|   d|  | d	dd
dd
f }|d	dd
dd
f }| d	dd
d
df }|d	dd
d
df }t||}t||| }| | j}||d	dd
dd
f< ||d	dd
d
df< d|d< |S )al  Compose two homogeneous transformations.

    .. math::
        T_0^{2} = \begin{bmatrix} R_0^1 R_1^{2} & R_0^{1} t_1^{2} + t_0^{1} \
        \\mathbf{0} & 1\end{bmatrix}

    Args:
        trans_01: tensor with the homogeneous transformation from
          a reference frame 1 respect to a frame 0. The tensor has must have a
          shape of :math:`(N, 4, 4)` or :math:`(4, 4)`.
        trans_12: tensor with the homogeneous transformation from
          a reference frame 2 respect to a frame 1. The tensor has must have a
          shape of :math:`(N, 4, 4)` or :math:`(4, 4)`.

    Returns:
        the transformation between the two frames with shape :math:`(N, 4, 4)` or :math:`(4, 4)`.

    Example::
        >>> trans_01 = torch.eye(4)  # 4x4
        >>> trans_12 = torch.eye(4)  # 4x4
        >>> trans_02 = compose_transformations(trans_01, trans_12)  # 4x4

          N   r   z8Input trans_01 must be a of the shape Nx4x4 or 4x4. Got z8Input trans_12 must be a of the shape Nx4x4 or 4x4. Got %Input number of dims must match. Got  and .r         ?.r   r   )r   dimshape
ValueErrortorchmatmul	new_zeros)	r   r   rmat_01rmat_12tvec_01tvec_12rmat_02tvec_02trans_02 r+   J/home/ubuntu/.local/lib/python3.10/site-packages/kornia/geometry/linalg.pyr
   '   s&   r
   c                 C  s   t |  |  dv r| jdd dkstd| j | dddddf }| dddddf }|d	d}t| |}| | j}|dddddf | |dddddf | d
|d< |S )a  Invert a 4x4 homogeneous transformation.

     :math:`T_1^{2} = \begin{bmatrix} R_1 & t_1 \\ \mathbf{0} & 1 \end{bmatrix}`

    The inverse transformation is computed as follows:

    .. math::

        T_2^{1} = (T_1^{2})^{-1} = \begin{bmatrix} R_1^T & -R_1^T t_1 \\
        \mathbf{0} & 1\end{bmatrix}

    Args:
        trans_12: transformation tensor of shape :math:`(N, 4, 4)` or :math:`(4, 4)`.

    Returns:
        tensor with inverted transformations with shape :math:`(N, 4, 4)` or :math:`(4, 4)`.

    Example:
        >>> trans_12 = torch.rand(1, 4, 4)  # Nx4x4
        >>> trans_21 = inverse_transformation(trans_12)  # Nx4x4

    r   r   Nr   z'Input size must be a Nx4x4 or 4x4. Got .r   r   r   r   )	r   r   r   r    	transposer!   r"   r#   copy_)r   r%   r'   rmat_21tvec_21trans_21r+   r+   r,   r   \   s   r   r*   c           
      C  sZ  t |  t | |  dv r| jdd dkstd| j | dv r.|jdd dks6td|j |  | ksLtd|   d|  | ddd	dd	f }| ddd	d	d
f }|ddd	dd	f }|ddd	d	d
f }|dd}t||}t||| }t| }	||	ddd	dd	f< ||	ddd	d	d
f< d|	d< |	S )ay  Compute the relative homogeneous transformation from a reference transformation.

    :math:`T_1^{0} = \begin{bmatrix} R_1 & t_1 \\ \mathbf{0} & 1 \end{bmatrix}` to destination :math:`T_2^{0} =
    \begin{bmatrix} R_2 & t_2 \\ \mathbf{0} & 1 \end{bmatrix}`.

    The relative transformation is computed as follows:

    .. math::

        T_1^{2} = (T_0^{1})^{-1} \cdot T_0^{2}

    Args:
        trans_01: reference transformation tensor of shape :math:`(N, 4, 4)` or :math:`(4, 4)`.
        trans_02: destination transformation tensor of shape :math:`(N, 4, 4)` or :math:`(4, 4)`.

    Returns:
        the relative transformation between the transformations with shape :math:`(N, 4, 4)` or :math:`(4, 4)`.

    Example::
        >>> trans_01 = torch.eye(4)  # 4x4
        >>> trans_02 = torch.eye(4)  # 4x4
        >>> trans_12 = relative_transformation(trans_01, trans_02)  # 4x4

    r   r   Nr   z/Input must be a of the shape Nx4x4 or 4x4. Got r   r   .r   r   r-   r   r   )r   r   r   r    r.   r!   r"   
zeros_like)
r   r*   r$   r&   r(   r)   rmat_10r%   r'   r   r+   r+   r,   r      s(   
r   points_1c                 C  s6  t |  t | | jd |jd ks%| jd dkr%td| j d|j | jd |jd d ks;td|  d| t|j}|d|jd |jd }| d| jd | jd } tj| t|jd | jd  dd} t|}t	|| 
dd	d}tj|dd
}t|}|jd |d< |jd |d< ||}|S )a  Apply transformations to a set of points.

    Args:
        trans_01: tensor for transformations of shape
          :math:`(B, D+1, D+1)`.
        points_1: tensor of points of shape :math:`(B, N, D)`.

    Returns:
        a tensor of N-dimensional points.

    Shape:
        - Output: :math:`(B, N, D)`

    Examples:
        >>> points_1 = torch.rand(2, 4, 3)  # BxNx3
        >>> trans_01 = torch.eye(4).view(1, 4, 4)  # Bx4x4
        >>> points_0 = transform_points(trans_01, points_1)  # BxNx3

    r      z=Input batch size must be the same for both tensors or 1. Got r   r-   z1Last input dimensions must differ by one unit Gotr   )repeatsr   r   )r   )r   r   r    listreshaper!   repeat_interleaveintr   bmmpermutesqueezer   )r   r5   	shape_inp
points_1_h
points_0_hpoints_0r+   r+   r,   r      s(   "
$
r   &.>pointlineepsfloatc                 C  s   t |  t | | jd dvrtd| j |jd dkr&td|j |d | d  }||d | d  7 }||d 7 }|  |d  |d    }|||  S )	a^  Return the distance from points to lines.

    Args:
       point: (possibly homogeneous) points :math:`(*, N, 2 or 3)`.
       line: lines coefficients :math:`(a, b, c)` with shape :math:`(*, N, 3)`, where :math:`ax + by + c = 0`.
       eps: Small constant for safe sqrt.

    Returns:
        the computed distance with shape :math:`(*, N)`.

    r-   r   z&pts must be a (*, 2 or 3) tensor. Got r   z#lines must be a (*, 3) tensor. Got ).r   ).r6   ).r   )r   r   r    abs_squaresqrt)rD   rE   rF   	numerator
denom_normr+   r+   r,   r      s   r   Fxykeepdimboolc                 C  s,   t | ddg t |ddg | | d|S )z#Return a batched version of .dot().*Nr-   )r   sum)rM   rN   rO   r+   r+   r,   r     s   r   c                 C  s   t | | |S )z$Return the squared norm of a vector.)r   )rM   rO   r+   r+   r,   r	     s   r	   ư>c                 C  s>   t | ddg t |ddg | | djd|d| S )a{  Compute the Euclidean distance between two set of n-dimensional points.

    More: https://en.wikipedia.org/wiki/Euclidean_distance

    Args:
        x: first set of points of shape :math:`(*, N)`.
        y: second set of points of shape :math:`(*, N)`.
        keepdim: whether to keep the dimension after reduction.
        eps: small value to have numerical stability.

    rQ   rR   r   r-   )r   rO   )r   powrS   add_sqrt_)rM   rN   rO   rF   r+   r+   r,   r     s   "r   )r   r   r   r   r   r   )r   r   r   r   )r   r   r*   r   r   r   )r   r   r5   r   r   r   )rC   )rD   r   rE   r   rF   rG   r   r   )F)rM   r   rN   r   rO   rP   r   r   )rM   r   rO   rP   r   r   )FrT   )
rM   r   rN   r   rO   rP   rF   rG   r   r   )
__future__r   r!   kornia.corer   kornia.core.checkr   r   kornia.geometry.conversionsr   r   __all__r
   r   r   r   r   r   r	   r   r   r+   r+   r+   r,   <module>   s   

5
+
12!