





from typing import Dict, List, Optional, Union

import numpy as np

from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict
from ...image_transforms import (
    get_resize_output_image_size,
    normalize,
    pad,
    rescale,
    resize,
    to_channel_dimension_format,
)
from ...image_utils import (
    IMAGENET_STANDARD_MEAN,
    IMAGENET_STANDARD_STD,
    ChannelDimension,
    ImageInput,
    PILImageResampling,
    get_image_size,
    make_list_of_images,
    to_numpy_array,
    valid_images,
)
from ...utils import TensorType, logging
from ...utils.import_utils import is_vision_available


SCREAMING_SNAKE_CASE_		  =			logging.get_logger(__name__)


if is_vision_available():
      import PIL

class 						UpperCamelCase__					( lowerCAmelCase_  ):



     '''simple docstring'''

     __snake_case       :      List[str]						      =     ["pixel_values"]






     def __init__(				self		:       Tuple		,lowerCamelCase__		:       bool = True		,lowerCamelCase__		:       Dict[str, int] = None		,lowerCamelCase__		:       PILImageResampling = PILImageResampling.BILINEAR		,lowerCamelCase__		:       bool = True		,lowerCamelCase__		:       bool = False		,lowerCamelCase__		:       bool = True		,lowerCamelCase__		:       bool = True		,lowerCamelCase__		:       Union[int, float] = 1 / 255		,lowerCamelCase__		:       bool = True		,lowerCamelCase__		:       Optional[Union[float, List[float]]] = None		,lowerCamelCase__		:       Optional[Union[float, List[float]]] = None		,**lowerCamelCase__		:       str		,)	->						None:




           '''simple docstring'''


           super().__init__(**lowerCamelCase__			)

           SCREAMING_SNAKE_CASE						=		size if size is not None else {"""height""": 2560, """width""": 1920}
           if isinstance(lowerCamelCase__		,(tuple, list)			):
                 # The previous feature extractor size parameter was in (width, height) format
                 SCREAMING_SNAKE_CASE						=		size[::-1]
           SCREAMING_SNAKE_CASE						=		get_size_dict(lowerCamelCase__			)

           SCREAMING_SNAKE_CASE						=		do_resize
           SCREAMING_SNAKE_CASE						=		size
           SCREAMING_SNAKE_CASE						=		resample
           SCREAMING_SNAKE_CASE						=		do_thumbnail
           SCREAMING_SNAKE_CASE						=		do_align_long_axis
           SCREAMING_SNAKE_CASE						=		do_pad
           SCREAMING_SNAKE_CASE						=		do_rescale
           SCREAMING_SNAKE_CASE						=		rescale_factor
           SCREAMING_SNAKE_CASE						=		do_normalize
           SCREAMING_SNAKE_CASE						=		image_mean if image_mean is not None else IMAGENET_STANDARD_MEAN
           SCREAMING_SNAKE_CASE						=		image_std if image_std is not None else IMAGENET_STANDARD_STD






     def 							SCREAMING_SNAKE_CASE__    (				self		:       Optional[int]		,lowerCamelCase__		:       np.ndarray		,lowerCamelCase__		:       Dict[str, int]		,lowerCamelCase__		:       Optional[Union[str, ChannelDimension]] = None			)	->						np.ndarray:




           '''simple docstring'''


           SCREAMING_SNAKE_CASE,   SCREAMING_SNAKE_CASE						=		get_image_size(lowerCamelCase__			)
           SCREAMING_SNAKE_CASE,   SCREAMING_SNAKE_CASE						=		size["""height"""], size["""width"""]

           if (output_width < output_height and input_width > input_height) or (
               output_width > output_height and input_width < input_height
           ):
                 SCREAMING_SNAKE_CASE						=		np.rotaa(lowerCamelCase__		,3			)

           if data_format is not None:
                 SCREAMING_SNAKE_CASE						=		to_channel_dimension_format(lowerCamelCase__		,lowerCamelCase__			)

           return image






     def 							SCREAMING_SNAKE_CASE__    (				self		:       List[Any]		,lowerCamelCase__		:       np.ndarray		,lowerCamelCase__		:       Dict[str, int]		,lowerCamelCase__		:       bool = False		,lowerCamelCase__		:       Optional[Union[str, ChannelDimension]] = None		,)	->						np.ndarray:




           '''simple docstring'''


           SCREAMING_SNAKE_CASE,   SCREAMING_SNAKE_CASE						=		size["""height"""], size["""width"""]
           SCREAMING_SNAKE_CASE,   SCREAMING_SNAKE_CASE						=		get_image_size(lowerCamelCase__			)

           SCREAMING_SNAKE_CASE						=		output_width - input_width
           SCREAMING_SNAKE_CASE						=		output_height - input_height

           if random_padding:
                 SCREAMING_SNAKE_CASE						=		np.random.randint(low=0		,high=delta_height + 1			)
                 SCREAMING_SNAKE_CASE						=		np.random.randint(low=0		,high=delta_width + 1			)
           else:
                 SCREAMING_SNAKE_CASE						=		delta_height // 2
                 SCREAMING_SNAKE_CASE						=		delta_width // 2

           SCREAMING_SNAKE_CASE						=		delta_height - pad_top
           SCREAMING_SNAKE_CASE						=		delta_width - pad_left

           SCREAMING_SNAKE_CASE						=		((pad_top, pad_bottom), (pad_left, pad_right))
           return pad(lowerCamelCase__		,lowerCamelCase__		,data_format=lowerCamelCase__			)






     def 							SCREAMING_SNAKE_CASE__    (				self		:       Tuple		,*lowerCamelCase__		:       Tuple		,**lowerCamelCase__		:       Optional[int]			)	->						List[str]:




           '''simple docstring'''


           logger.info("""pad is deprecated and will be removed in version 4.27. Please use pad_image instead."""			)
           return self.pad_image(*lowerCamelCase__		,**lowerCamelCase__			)






     def 							SCREAMING_SNAKE_CASE__    (				self		:       Any		,lowerCamelCase__		:       np.ndarray		,lowerCamelCase__		:       Dict[str, int]		,lowerCamelCase__		:       PILImageResampling = PILImageResampling.BICUBIC		,lowerCamelCase__		:       Optional[Union[str, ChannelDimension]] = None		,**lowerCamelCase__		:       str		,)	->						np.ndarray:




           '''simple docstring'''


           SCREAMING_SNAKE_CASE,   SCREAMING_SNAKE_CASE						=		get_image_size(lowerCamelCase__			)
           SCREAMING_SNAKE_CASE,   SCREAMING_SNAKE_CASE						=		size["""height"""], size["""width"""]

           # We always resize to the smallest of either the input or output size.
           SCREAMING_SNAKE_CASE						=		min(lowerCamelCase__		,lowerCamelCase__			)
           SCREAMING_SNAKE_CASE						=		min(lowerCamelCase__		,lowerCamelCase__			)

           if height == input_height and width == input_width:
                 return image

           if input_height > input_width:
                 SCREAMING_SNAKE_CASE						=		int(input_width * height / input_height			)
           elif input_width > input_height:
                 SCREAMING_SNAKE_CASE						=		int(input_height * width / input_width			)

           return resize(
               lowerCamelCase__		,size=(height, width)		,resample=lowerCamelCase__		,reducing_gap=2.0		,data_format=lowerCamelCase__		,**lowerCamelCase__			)






     def 							SCREAMING_SNAKE_CASE__    (				self		:       int		,lowerCamelCase__		:       np.ndarray		,lowerCamelCase__		:       Dict[str, int]		,lowerCamelCase__		:       PILImageResampling = PILImageResampling.BICUBIC		,lowerCamelCase__		:       Optional[Union[str, ChannelDimension]] = None		,**lowerCamelCase__		:       Optional[int]		,)	->						np.ndarray:




           '''simple docstring'''


           SCREAMING_SNAKE_CASE						=		get_size_dict(lowerCamelCase__			)
           SCREAMING_SNAKE_CASE						=		min(size["""height"""]		,size["""width"""]			)
           SCREAMING_SNAKE_CASE						=		get_resize_output_image_size(lowerCamelCase__		,size=lowerCamelCase__		,default_to_square=lowerCamelCase__			)
           SCREAMING_SNAKE_CASE						=		resize(lowerCamelCase__		,size=lowerCamelCase__		,resample=lowerCamelCase__		,data_format=lowerCamelCase__		,**lowerCamelCase__			)
           return resized_image






     def 							SCREAMING_SNAKE_CASE__    (				self		:       int		,lowerCamelCase__		:       np.ndarray		,lowerCamelCase__		:       Union[int, float]		,lowerCamelCase__		:       Optional[Union[str, ChannelDimension]] = None		,**lowerCamelCase__		:       Optional[int]		,)	->						List[Any]:




           '''simple docstring'''


           return rescale(lowerCamelCase__		,scale=lowerCamelCase__		,data_format=lowerCamelCase__		,**lowerCamelCase__			)






     def 							SCREAMING_SNAKE_CASE__    (				self		:       int		,lowerCamelCase__		:       np.ndarray		,lowerCamelCase__		:       Union[float, List[float]]		,lowerCamelCase__		:       Union[float, List[float]]		,lowerCamelCase__		:       Optional[Union[str, ChannelDimension]] = None		,**lowerCamelCase__		:       List[Any]		,)	->						np.ndarray:




           '''simple docstring'''


           return normalize(lowerCamelCase__		,mean=lowerCamelCase__		,std=lowerCamelCase__		,data_format=lowerCamelCase__		,**lowerCamelCase__			)






     def 							SCREAMING_SNAKE_CASE__    (				self		:       Tuple		,lowerCamelCase__		:       ImageInput		,lowerCamelCase__		:       bool = None		,lowerCamelCase__		:       Dict[str, int] = None		,lowerCamelCase__		:       PILImageResampling = None		,lowerCamelCase__		:       bool = None		,lowerCamelCase__		:       bool = None		,lowerCamelCase__		:       bool = None		,lowerCamelCase__		:       bool = False		,lowerCamelCase__		:       bool = None		,lowerCamelCase__		:       float = None		,lowerCamelCase__		:       bool = None		,lowerCamelCase__		:       Optional[Union[float, List[float]]] = None		,lowerCamelCase__		:       Optional[Union[float, List[float]]] = None		,lowerCamelCase__		:       Optional[Union[str, TensorType]] = None		,lowerCamelCase__		:       Optional[ChannelDimension] = ChannelDimension.FIRST		,**lowerCamelCase__		:       Optional[int]		,)	->						PIL.Image.Image:




           '''simple docstring'''


           SCREAMING_SNAKE_CASE						=		do_resize if do_resize is not None else self.do_resize
           SCREAMING_SNAKE_CASE						=		size if size is not None else self.size
           if isinstance(lowerCamelCase__		,(tuple, list)			):
                 # Previous feature extractor had size in (width, height) format
                 SCREAMING_SNAKE_CASE						=		size[::-1]
           SCREAMING_SNAKE_CASE						=		get_size_dict(lowerCamelCase__			)
           SCREAMING_SNAKE_CASE						=		resample if resample is not None else self.resample
           SCREAMING_SNAKE_CASE						=		do_thumbnail if do_thumbnail is not None else self.do_thumbnail
           SCREAMING_SNAKE_CASE						=		do_align_long_axis if do_align_long_axis is not None else self.do_align_long_axis
           SCREAMING_SNAKE_CASE						=		do_pad if do_pad is not None else self.do_pad
           SCREAMING_SNAKE_CASE						=		do_rescale if do_rescale is not None else self.do_rescale
           SCREAMING_SNAKE_CASE						=		rescale_factor if rescale_factor is not None else self.rescale_factor
           SCREAMING_SNAKE_CASE						=		do_normalize if do_normalize is not None else self.do_normalize
           SCREAMING_SNAKE_CASE						=		image_mean if image_mean is not None else self.image_mean
           SCREAMING_SNAKE_CASE						=		image_std if image_std is not None else self.image_std

           SCREAMING_SNAKE_CASE						=		make_list_of_images(lowerCamelCase__			)

           if not valid_images(lowerCamelCase__			):
                 raise ValueError(
                     """Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, """
                     """torch.Tensor, tf.Tensor or jax.ndarray."""			)

           if do_resize and size is None:
                 raise ValueError("""Size must be specified if do_resize is True."""			)

           if do_rescale and rescale_factor is None:
                 raise ValueError("""Rescale factor must be specified if do_rescale is True."""			)

           if do_pad and size is None:
                 raise ValueError("""Size must be specified if do_pad is True."""			)

           if do_normalize and (image_mean is None or image_std is None):
                 raise ValueError("""Image mean and std must be specified if do_normalize is True."""			)

           # All transformations expect numpy arrays.
           SCREAMING_SNAKE_CASE						=		[to_numpy_array(lowerCamelCase__			) for image in images]

           if do_align_long_axis:
                 SCREAMING_SNAKE_CASE						=		[self.align_long_axis(lowerCamelCase__		,size=lowerCamelCase__			) for image in images]

           if do_resize:
                 SCREAMING_SNAKE_CASE						=		[self.resize(image=lowerCamelCase__		,size=lowerCamelCase__		,resample=lowerCamelCase__			) for image in images]

           if do_thumbnail:
                 SCREAMING_SNAKE_CASE						=		[self.thumbnail(image=lowerCamelCase__		,size=lowerCamelCase__			) for image in images]

           if do_pad:
                 SCREAMING_SNAKE_CASE						=		[self.pad_image(image=lowerCamelCase__		,size=lowerCamelCase__		,random_padding=lowerCamelCase__			) for image in images]

           if do_rescale:
                 SCREAMING_SNAKE_CASE						=		[self.rescale(image=lowerCamelCase__		,scale=lowerCamelCase__			) for image in images]

           if do_normalize:
                 SCREAMING_SNAKE_CASE						=		[self.normalize(image=lowerCamelCase__		,mean=lowerCamelCase__		,std=lowerCamelCase__			) for image in images]

           SCREAMING_SNAKE_CASE						=		[to_channel_dimension_format(lowerCamelCase__		,lowerCamelCase__			) for image in images]

           SCREAMING_SNAKE_CASE						=		{"""pixel_values""": images}
           return BatchFeature(data=lowerCamelCase__		,tensor_type=lowerCamelCase__			)









from __future__ import annotations

from collections.abc import Iterable

class 						UpperCamelCase__					:



     '''simple docstring'''

     def __init__(				self		:       Optional[Any]		,lowerCamelCase__		:       Optional[int]		,lowerCamelCase__		:       List[Any]			)	->						int:




           '''simple docstring'''


           SCREAMING_SNAKE_CASE,   SCREAMING_SNAKE_CASE						=		float(lowerCamelCase__			), float(lowerCamelCase__			)






     def __eq__(				self		:       int		,lowerCamelCase__		:       Union[str, Any]			)	->						List[str]:




           '''simple docstring'''


           return self.x == other.x and self.y == other.y






     def __ne__(				self		:       Optional[int]		,lowerCamelCase__		:       int			)	->						Dict:




           '''simple docstring'''


           return not self == other






     def __gt__(				self		:       Optional[Any]		,lowerCamelCase__		:       Optional[Any]			)	->						List[Any]:




           '''simple docstring'''


           if self.x > other.x:
                 return True
           elif self.x == other.x:
                 return self.y > other.y
           return False






     def __lt__(				self		:       Union[str, Any]		,lowerCamelCase__		:       Optional[Any]			)	->						Optional[Any]:




           '''simple docstring'''


           return not self > other






     def __ge__(				self		:       Optional[Any]		,lowerCamelCase__		:       Tuple			)	->						Optional[Any]:




           '''simple docstring'''


           if self.x > other.x:
                 return True
           elif self.x == other.x:
                 return self.y >= other.y
           return False






     def __le__(				self		:       Tuple		,lowerCamelCase__		:       int			)	->						Dict:




           '''simple docstring'''


           if self.x < other.x:
                 return True
           elif self.x == other.x:
                 return self.y <= other.y
           return False






     def __repr__(				self		:       Dict			)	->						Any:




           '''simple docstring'''


           return F"""({self.x}, {self.y})"""






     def __hash__(				self		:       List[Any]			)	->						List[Any]:




           '''simple docstring'''


           return hash(self.x			)



def   __lowercase  ( _SCREAMING_SNAKE_CASE					,		)					->  list[Point]:


      '''simple docstring'''


      SCREAMING_SNAKE_CASE						=		[]
      if list_of_tuples:
            for p in list_of_tuples:
                  if isinstance(_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE      ):
                        points.append(_SCREAMING_SNAKE_CASE      )
                  else:
                        try:
                              points.append(Point(p[0]					,		p[1]      )      )
                        except (IndexError, TypeError):
                              print(
                                  F"""Ignoring deformed point {p}. All points"""
                                  """ must have at least 2 coordinates."""      )
      return points



def   __lowercase  ( _SCREAMING_SNAKE_CASE      )					->  list[Point]:


      '''simple docstring'''


      if not hasattr(_SCREAMING_SNAKE_CASE					,		"""__iter__"""      ):
            SCREAMING_SNAKE_CASE						=		F"""Expecting an iterable object but got an non-iterable type {points}"""
            raise ValueError(_SCREAMING_SNAKE_CASE      )

      if not points:
            SCREAMING_SNAKE_CASE						=		F"""Expecting a list of points but got {points}"""
            raise ValueError(_SCREAMING_SNAKE_CASE      )

      return _construct_points(_SCREAMING_SNAKE_CASE      )



def   __lowercase  ( _SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE      )					->  float:


      '''simple docstring'''


      SCREAMING_SNAKE_CASE						=		(a.x * b.y + b.x * c.y + c.x * a.y) - (a.y * b.x + b.y * c.x + c.y * a.x)
      return det



def   __lowercase  ( _SCREAMING_SNAKE_CASE      )					->  list[Point]:


      '''simple docstring'''


      SCREAMING_SNAKE_CASE						=		sorted(_validate_input(_SCREAMING_SNAKE_CASE      )      )
      SCREAMING_SNAKE_CASE						=		len(_SCREAMING_SNAKE_CASE      )
      SCREAMING_SNAKE_CASE						=		set()

      for i in range(n - 1      ):
            for j in range(i + 1					,		_SCREAMING_SNAKE_CASE      ):
                  SCREAMING_SNAKE_CASE						=		SCREAMING_SNAKE_CASE						=		False
                  SCREAMING_SNAKE_CASE						=		True
                  for k in range(_SCREAMING_SNAKE_CASE      ):
                        if k != i and k != j:
                              SCREAMING_SNAKE_CASE						=		_det(points[i]					,		points[j]					,		points[k]      )

                              if det_k > 0:
                                    SCREAMING_SNAKE_CASE						=		True
                              elif det_k < 0:
                                    SCREAMING_SNAKE_CASE						=		True
                              else:
                                    # point[i], point[j], point[k] all lie on a straight line
                                    # if point[k] is to the left of point[i] or it's to the
                                    # right of point[j], then point[i], point[j] cannot be
                                    # part of the convex hull of A
                                    if points[k] < points[i] or points[k] > points[j]:
                                          SCREAMING_SNAKE_CASE						=		False
                                          break

                        if points_left_of_ij and points_right_of_ij:
                              SCREAMING_SNAKE_CASE						=		False
                              break

                  if ij_part_of_convex_hull:
                        convex_set.update([points[i], points[j]]      )

      return sorted(_SCREAMING_SNAKE_CASE      )



def   __lowercase  ( _SCREAMING_SNAKE_CASE      )					->  list[Point]:


      '''simple docstring'''


      SCREAMING_SNAKE_CASE						=		sorted(_validate_input(_SCREAMING_SNAKE_CASE      )      )
      SCREAMING_SNAKE_CASE						=		len(_SCREAMING_SNAKE_CASE      )

      # divide all the points into an upper hull and a lower hull
      # the left most point and the right most point are definitely
      # members of the convex hull by definition.
      # use these two anchors to divide all the points into two hulls,
      # an upper hull and a lower hull.

      # all points to the left (above) the line joining the extreme points belong to the
      # upper hull
      # all points to the right (below) the line joining the extreme points below to the
      # lower hull
      # ignore all points on the line joining the extreme points since they cannot be
      # part of the convex hull

      SCREAMING_SNAKE_CASE						=		points[0]
      SCREAMING_SNAKE_CASE						=		points[n - 1]

      SCREAMING_SNAKE_CASE						=		{left_most_point, right_most_point}
      SCREAMING_SNAKE_CASE						=		[]
      SCREAMING_SNAKE_CASE						=		[]

      for i in range(1					,		n - 1      ):
            SCREAMING_SNAKE_CASE						=		_det(_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE					,		points[i]      )

            if det > 0:
                  upper_hull.append(points[i]      )
            elif det < 0:
                  lower_hull.append(points[i]      )

      _construct_hull(_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE      )
      _construct_hull(_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE      )

      return sorted(_SCREAMING_SNAKE_CASE      )



def   __lowercase  ( _SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE      )					->  None:


      '''simple docstring'''


      if points:
            SCREAMING_SNAKE_CASE						=		None
            SCREAMING_SNAKE_CASE						=		float("""-inf"""      )
            SCREAMING_SNAKE_CASE						=		[]

            for p in points:
                  SCREAMING_SNAKE_CASE						=		_det(_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE      )

                  if det > 0:
                        candidate_points.append(_SCREAMING_SNAKE_CASE      )

                        if det > extreme_point_distance:
                              SCREAMING_SNAKE_CASE						=		det
                              SCREAMING_SNAKE_CASE						=		p

            if extreme_point:
                  _construct_hull(_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE      )
                  convex_set.add(_SCREAMING_SNAKE_CASE      )
                  _construct_hull(_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE      )



def   __lowercase  ( _SCREAMING_SNAKE_CASE      )					->  list[Point]:


      '''simple docstring'''


      SCREAMING_SNAKE_CASE						=		sorted(_validate_input(_SCREAMING_SNAKE_CASE      )      )
      SCREAMING_SNAKE_CASE						=		len(_SCREAMING_SNAKE_CASE      )

      SCREAMING_SNAKE_CASE						=		points[:2]
      for i in range(2					,		_SCREAMING_SNAKE_CASE      ):
            SCREAMING_SNAKE_CASE						=		_det(convex_hull[1]					,		convex_hull[0]					,		points[i]      )
            if det > 0:
                  convex_hull.insert(0					,		points[i]      )
                  break
            elif det < 0:
                  convex_hull.append(points[i]      )
                  break
            else:
                  SCREAMING_SNAKE_CASE						=		points[i]
      i += 1

      for j in range(_SCREAMING_SNAKE_CASE					,		_SCREAMING_SNAKE_CASE      ):
            if (
                _det(convex_hull[0]					,		convex_hull[-1]					,		points[j]      ) > 0
                and _det(convex_hull[-1]					,		convex_hull[0]					,		points[1]      ) < 0
            ):
                  # The point lies within the convex hull
                  continue

            convex_hull.insert(0					,		points[j]      )
            convex_hull.append(points[j]      )
            while _det(convex_hull[0]					,		convex_hull[1]					,		convex_hull[2]      ) >= 0:
                  del convex_hull[1]
            while _det(convex_hull[-1]					,		convex_hull[-2]					,		convex_hull[-3]      ) <= 0:
                  del convex_hull[-2]

    # `convex_hull` is contains the convex hull in circular order
      return sorted(convex_hull[1:] if len(_SCREAMING_SNAKE_CASE      ) > 3 else convex_hull      )



def   __lowercase  ( )					->  Any:


      '''simple docstring'''


      SCREAMING_SNAKE_CASE						=		[
          (0, 3),
          (2, 2),
          (1, 1),
          (2, 1),
          (3, 0),
          (0, 0),
          (3, 3),
          (2, -1),
          (2, -4),
          (1, -3),
      ]
      # the convex set of points is
      # [(0, 0), (0, 3), (1, -3), (2, -4), (3, 0), (3, 3)]
      SCREAMING_SNAKE_CASE						=		convex_hull_bf(_SCREAMING_SNAKE_CASE      )

      SCREAMING_SNAKE_CASE						=		convex_hull_recursive(_SCREAMING_SNAKE_CASE      )
      assert results_bf == results_recursive

      SCREAMING_SNAKE_CASE						=		convex_hull_melkman(_SCREAMING_SNAKE_CASE      )
      assert results_bf == results_melkman

      print(_SCREAMING_SNAKE_CASE      )


if __name__ == "__main__":
      main()


