1 # SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries
3 # SPDX-License-Identifier: MIT
7 ================================================================================
9 vectorio Polygon for Blinka
11 **Software and Dependencies:**
14 https://github.com/adafruit/Adafruit_Blinka/releases
16 * Author(s): Melissa LeBlanc-Williams
20 from typing import Union, Tuple, List
21 from displayio._colorconverter import ColorConverter
22 from displayio._palette import Palette
23 from displayio._area import Area
24 from ._vectorshape import _VectorShape
26 __version__ = "0.0.0+auto.0"
27 __repo__ = "https://github.com/adafruit/Adafruit_Blinka_displayio.git"
30 class Polygon(_VectorShape):
31 """Vectorio Polygon"""
36 pixel_shader: Union[ColorConverter, Palette],
37 points: List[Tuple[int, int]],
41 """Represents a closed shape by ordered vertices. The path will be treated as
42 'closed', the last point will connect to the first point.
44 :param Union[~displayio.ColorConverter,~displayio.Palette] pixel_shader: The pixel
45 shader that produces colors from values
46 :param List[Tuple[int,int]] points: Vertices for the polygon
47 :param int x: Initial screen x position of the 0,0 origin in the points list.
48 :param int y: Initial screen y position of the 0,0 origin in the points list.
49 :param int color_index: Initial color_index to use when selecting color from the palette.
53 super().__init__(pixel_shader, x, y)
57 def points(self) -> List[Tuple[int, int]]:
58 """The points of the polygon in pixels"""
62 def points(self, value: List[Tuple[int, int]]) -> None:
64 raise ValueError("Polygon needs at least 3 points")
66 self._shape_set_dirty()
69 def color_index(self) -> int:
70 """The color_index of the polygon as 0 based index of the palette."""
71 return self._color_index - 1
74 def color_index(self, value: int) -> None:
75 self._color_index = abs(value + 1)
76 self._shape_set_dirty()
87 # pylint: disable=too-many-arguments
88 return (point_x - line_x1) * (line_y2 - line_y1) - (point_y - line_y1) * (
92 def _get_pixel(self, x: int, y: int) -> int:
93 # pylint: disable=invalid-name
94 if len(self._points) == 0:
97 x1 = self._points[0][0]
98 y1 = self._points[0][1]
99 for i in range(1, len(self._points)):
100 x2 = self._points[i][0]
101 y2 = self._points[i][1]
103 if y2 > y and self._line_side(x1, y1, x2, y2, x, y) < 0:
104 # Wind up, point is to the left of the edge vector
106 elif y2 <= y and self._line_side(x1, y1, x2, y2, x, y) > 0:
107 # Wind down, point is to the right of the edge vector
112 return 0 if winding_number == 0 else self._color_index
114 def _get_area(self, out_area: Area) -> None:
115 # Figure out the shape dimensions by using min and max
121 for x, y in self._points: