vkit.element.point

  1# Copyright 2022 vkit-x Administrator. All Rights Reserved.
  2#
  3# This project (vkit-x/vkit) is dual-licensed under commercial and SSPL licenses.
  4#
  5# The commercial license gives you the full rights to create and distribute software
  6# on your own terms without any SSPL license obligations. For more information,
  7# please see the "LICENSE_COMMERCIAL.txt" file.
  8#
  9# This project is also available under Server Side Public License (SSPL).
 10# The SSPL licensing is ideal for use cases such as open source projects with
 11# SSPL distribution, student/academic purposes, hobby projects, internal research
 12# projects without external distribution, or other projects where all SSPL
 13# obligations can be met. For more information, please see the "LICENSE_SSPL.txt" file.
 14from typing import Optional, Tuple, Union, List, Sequence, Iterable
 15from itertools import chain
 16
 17import attrs
 18import numpy as np
 19
 20from .type import Shapable
 21from .opt import (
 22    extract_shape_from_shapable_or_shape,
 23    clip_val,
 24    resize_val,
 25    generate_shape_and_resized_shape,
 26)
 27
 28_T = Union[float, str]
 29
 30
 31@attrs.define(frozen=True)
 32class Point:
 33    # Smooth positioning is crucial for geometric distortion.
 34    #
 35    # NOTE: Setting `eq=False` to avoid comparing the float fields directly.
 36    # In order words, `point0 == point1` checks only `y` and `x` fields.
 37    smooth_y: float = attrs.field(eq=False)
 38    smooth_x: float = attrs.field(eq=False)
 39
 40    # NOTE: Setting `hash=False` is necessary since this class is frozen
 41    # and these fields will be set in `__attrs_post_init__`.
 42    y: int = attrs.field(init=False, hash=False)
 43    x: int = attrs.field(init=False, hash=False)
 44
 45    def __attrs_post_init__(self):
 46        object.__setattr__(self, 'y', round(self.smooth_y))
 47        object.__setattr__(self, 'x', round(self.smooth_x))
 48
 49    ###############
 50    # Constructor #
 51    ###############
 52    @classmethod
 53    def create(cls, y: _T, x: _T):
 54        return cls(smooth_y=float(y), smooth_x=float(x))
 55
 56    ##############
 57    # Conversion #
 58    ##############
 59    @classmethod
 60    def from_xy_pair(cls, xy_pair: Tuple[_T, _T]):
 61        x, y = xy_pair
 62        return cls.create(y=y, x=x)
 63
 64    def to_xy_pair(self):
 65        return (self.x, self.y)
 66
 67    def to_smooth_xy_pair(self):
 68        return (self.smooth_x, self.smooth_y)
 69
 70    ############
 71    # Operator #
 72    ############
 73    def to_clipped_point(self, shapable_or_shape: Union[Shapable, Tuple[int, int]]):
 74        height, width = extract_shape_from_shapable_or_shape(shapable_or_shape)
 75        if 0 <= self.y < height and 0 <= self.x < width:
 76            return self
 77        else:
 78            return Point.create(
 79                y=clip_val(self.smooth_y, height),
 80                x=clip_val(self.smooth_x, width),
 81            )
 82
 83    def to_shifted_point(self, offset_y: int = 0, offset_x: int = 0):
 84        return Point.create(
 85            y=self.smooth_y + offset_y,
 86            x=self.smooth_x + offset_x,
 87        )
 88
 89    def to_conducted_resized_point(
 90        self,
 91        shapable_or_shape: Union[Shapable, Tuple[int, int]],
 92        resized_height: Optional[int] = None,
 93        resized_width: Optional[int] = None,
 94    ):
 95        (
 96            height,
 97            width,
 98            resized_height,
 99            resized_width,
100        ) = generate_shape_and_resized_shape(
101            shapable_or_shape=shapable_or_shape,
102            resized_height=resized_height,
103            resized_width=resized_width
104        )
105        return Point.create(
106            y=resize_val(self.smooth_y, height, resized_height),
107            x=resize_val(self.smooth_x, width, resized_width),
108        )
109
110
111class PointList(List[Point]):
112
113    ###############
114    # Constructor #
115    ###############
116    @classmethod
117    def from_point(cls, point: Point):
118        return cls((point,))
119
120    ##############
121    # Conversion #
122    ##############
123    @classmethod
124    def from_xy_pairs(cls, xy_pairs: Iterable[Tuple[_T, _T]]):
125        return cls(Point.from_xy_pair(xy_pair) for xy_pair in xy_pairs)
126
127    def to_xy_pairs(self):
128        return [point.to_xy_pair() for point in self]
129
130    def to_smooth_xy_pairs(self):
131        return [point.to_smooth_xy_pair() for point in self]
132
133    @classmethod
134    def from_flatten_xy_pairs(cls, flatten_xy_pairs: Sequence[_T]):
135        # [x0, y0, x1, y1, ...]
136        flatten_xy_pairs = tuple(flatten_xy_pairs)
137        assert flatten_xy_pairs and len(flatten_xy_pairs) % 2 == 0
138
139        points = PointList()
140        idx = 0
141        while idx < len(flatten_xy_pairs):
142            x = flatten_xy_pairs[idx]
143            y = flatten_xy_pairs[idx + 1]
144            points.append(Point.create(y=y, x=x))
145            idx += 2
146
147        return points
148
149    def to_flatten_xy_pairs(self):
150        return list(chain.from_iterable(point.to_xy_pair() for point in self))
151
152    def to_smooth_flatten_xy_pairs(self):
153        return list(chain.from_iterable(point.to_smooth_xy_pair() for point in self))
154
155    @classmethod
156    def from_np_array(cls, np_points: np.ndarray):
157        points = PointList()
158        for np_point in np_points:
159            x, y = np_point
160            points.append(Point.create(y=y, x=x))
161
162        if len(points) > 2 and points[0] == points[-1]:
163            # Handle the circled duplicated points generated by package like shapely.
164            points.pop()
165
166        return points
167
168    def to_np_array(self):
169        return np.asarray(self.to_xy_pairs(), dtype=np.int32)
170
171    def to_smooth_np_array(self):
172        return np.asarray(self.to_smooth_xy_pairs(), dtype=np.float32)
173
174    def to_point_tuple(self):
175        return PointTuple(self)
176
177    ############
178    # Operator #
179    ############
180    def copy(self):
181        return PointList(self)
182
183    def to_clipped_points(self, shapable_or_shape: Union[Shapable, Tuple[int, int]]):
184        return PointList(point.to_clipped_point(shapable_or_shape) for point in self)
185
186    def to_shifted_points(self, offset_y: int = 0, offset_x: int = 0):
187        return PointList(
188            point.to_shifted_point(
189                offset_y=offset_y,
190                offset_x=offset_x,
191            ) for point in self
192        )
193
194    def to_relative_points(self, origin_y: int, origin_x: int):
195        return self.to_shifted_points(offset_y=-origin_y, offset_x=-origin_x)
196
197    def to_conducted_resized_points(
198        self,
199        shapable_or_shape: Union[Shapable, Tuple[int, int]],
200        resized_height: Optional[int] = None,
201        resized_width: Optional[int] = None,
202    ):
203        return PointList(
204            point.to_conducted_resized_point(
205                shapable_or_shape=shapable_or_shape,
206                resized_height=resized_height,
207                resized_width=resized_width,
208            ) for point in self
209        )
210
211
212class PointTuple(Tuple[Point, ...]):
213
214    ###############
215    # Constructor #
216    ###############
217    @classmethod
218    def from_point(cls, point: Point):
219        return cls((point,))
220
221    ##############
222    # Conversion #
223    ##############
224    @classmethod
225    def from_xy_pairs(cls, xy_pairs: Iterable[Tuple[_T, _T]]):
226        return PointTuple(Point.from_xy_pair(xy_pair) for xy_pair in xy_pairs)
227
228    def to_xy_pairs(self):
229        return tuple(point.to_xy_pair() for point in self)
230
231    def to_smooth_xy_pairs(self):
232        return tuple(point.to_smooth_xy_pair() for point in self)
233
234    @classmethod
235    def from_flatten_xy_pairs(cls, flatten_xy_pairs: Sequence[_T]):
236        return PointList.from_flatten_xy_pairs(flatten_xy_pairs).to_point_tuple()
237
238    def to_flatten_xy_pairs(self):
239        return tuple(chain.from_iterable(point.to_xy_pair() for point in self))
240
241    def to_smooth_flatten_xy_pairs(self):
242        return tuple(chain.from_iterable(point.to_smooth_xy_pair() for point in self))
243
244    @classmethod
245    def from_np_array(cls, np_points: np.ndarray):
246        return PointList.from_np_array(np_points).to_point_tuple()
247
248    def to_np_array(self):
249        return np.asarray(self.to_xy_pairs(), dtype=np.int32)
250
251    def to_smooth_np_array(self):
252        return np.asarray(self.to_xy_pairs(), dtype=np.float32)
253
254    ############
255    # Operator #
256    ############
257    def to_clipped_points(self, shapable_or_shape: Union[Shapable, Tuple[int, int]]):
258        return PointTuple(point.to_clipped_point(shapable_or_shape) for point in self)
259
260    def to_shifted_points(self, offset_y: int = 0, offset_x: int = 0):
261        return PointTuple(
262            point.to_shifted_point(
263                offset_y=offset_y,
264                offset_x=offset_x,
265            ) for point in self
266        )
267
268    def to_relative_points(self, origin_y: int, origin_x: int):
269        return self.to_shifted_points(offset_y=-origin_y, offset_x=-origin_x)
270
271    def to_conducted_resized_points(
272        self,
273        shapable_or_shape: Union[Shapable, Tuple[int, int]],
274        resized_height: Optional[int] = None,
275        resized_width: Optional[int] = None,
276    ):
277        return PointTuple(
278            point.to_conducted_resized_point(
279                shapable_or_shape=shapable_or_shape,
280                resized_height=resized_height,
281                resized_width=resized_width,
282            ) for point in self
283        )
class Point:
 33class Point:
 34    # Smooth positioning is crucial for geometric distortion.
 35    #
 36    # NOTE: Setting `eq=False` to avoid comparing the float fields directly.
 37    # In order words, `point0 == point1` checks only `y` and `x` fields.
 38    smooth_y: float = attrs.field(eq=False)
 39    smooth_x: float = attrs.field(eq=False)
 40
 41    # NOTE: Setting `hash=False` is necessary since this class is frozen
 42    # and these fields will be set in `__attrs_post_init__`.
 43    y: int = attrs.field(init=False, hash=False)
 44    x: int = attrs.field(init=False, hash=False)
 45
 46    def __attrs_post_init__(self):
 47        object.__setattr__(self, 'y', round(self.smooth_y))
 48        object.__setattr__(self, 'x', round(self.smooth_x))
 49
 50    ###############
 51    # Constructor #
 52    ###############
 53    @classmethod
 54    def create(cls, y: _T, x: _T):
 55        return cls(smooth_y=float(y), smooth_x=float(x))
 56
 57    ##############
 58    # Conversion #
 59    ##############
 60    @classmethod
 61    def from_xy_pair(cls, xy_pair: Tuple[_T, _T]):
 62        x, y = xy_pair
 63        return cls.create(y=y, x=x)
 64
 65    def to_xy_pair(self):
 66        return (self.x, self.y)
 67
 68    def to_smooth_xy_pair(self):
 69        return (self.smooth_x, self.smooth_y)
 70
 71    ############
 72    # Operator #
 73    ############
 74    def to_clipped_point(self, shapable_or_shape: Union[Shapable, Tuple[int, int]]):
 75        height, width = extract_shape_from_shapable_or_shape(shapable_or_shape)
 76        if 0 <= self.y < height and 0 <= self.x < width:
 77            return self
 78        else:
 79            return Point.create(
 80                y=clip_val(self.smooth_y, height),
 81                x=clip_val(self.smooth_x, width),
 82            )
 83
 84    def to_shifted_point(self, offset_y: int = 0, offset_x: int = 0):
 85        return Point.create(
 86            y=self.smooth_y + offset_y,
 87            x=self.smooth_x + offset_x,
 88        )
 89
 90    def to_conducted_resized_point(
 91        self,
 92        shapable_or_shape: Union[Shapable, Tuple[int, int]],
 93        resized_height: Optional[int] = None,
 94        resized_width: Optional[int] = None,
 95    ):
 96        (
 97            height,
 98            width,
 99            resized_height,
100            resized_width,
101        ) = generate_shape_and_resized_shape(
102            shapable_or_shape=shapable_or_shape,
103            resized_height=resized_height,
104            resized_width=resized_width
105        )
106        return Point.create(
107            y=resize_val(self.smooth_y, height, resized_height),
108            x=resize_val(self.smooth_x, width, resized_width),
109        )
Point(smooth_y: float, smooth_x: float)
2def __init__(self, smooth_y, smooth_x):
3    _setattr = _cached_setattr_get(self)
4    _setattr('smooth_y', smooth_y)
5    _setattr('smooth_x', smooth_x)
6    self.__attrs_post_init__()

Method generated by attrs for class Point.

@classmethod
def create(cls, y: Union[float, str], x: Union[float, str]):
53    @classmethod
54    def create(cls, y: _T, x: _T):
55        return cls(smooth_y=float(y), smooth_x=float(x))
@classmethod
def from_xy_pair(cls, xy_pair: Tuple[Union[float, str], Union[float, str]]):
60    @classmethod
61    def from_xy_pair(cls, xy_pair: Tuple[_T, _T]):
62        x, y = xy_pair
63        return cls.create(y=y, x=x)
def to_xy_pair(self):
65    def to_xy_pair(self):
66        return (self.x, self.y)
def to_smooth_xy_pair(self):
68    def to_smooth_xy_pair(self):
69        return (self.smooth_x, self.smooth_y)
def to_clipped_point( self, shapable_or_shape: Union[vkit.element.type.Shapable, Tuple[int, int]]):
74    def to_clipped_point(self, shapable_or_shape: Union[Shapable, Tuple[int, int]]):
75        height, width = extract_shape_from_shapable_or_shape(shapable_or_shape)
76        if 0 <= self.y < height and 0 <= self.x < width:
77            return self
78        else:
79            return Point.create(
80                y=clip_val(self.smooth_y, height),
81                x=clip_val(self.smooth_x, width),
82            )
def to_shifted_point(self, offset_y: int = 0, offset_x: int = 0):
84    def to_shifted_point(self, offset_y: int = 0, offset_x: int = 0):
85        return Point.create(
86            y=self.smooth_y + offset_y,
87            x=self.smooth_x + offset_x,
88        )
def to_conducted_resized_point( self, shapable_or_shape: Union[vkit.element.type.Shapable, Tuple[int, int]], resized_height: Union[int, NoneType] = None, resized_width: Union[int, NoneType] = None):
 90    def to_conducted_resized_point(
 91        self,
 92        shapable_or_shape: Union[Shapable, Tuple[int, int]],
 93        resized_height: Optional[int] = None,
 94        resized_width: Optional[int] = None,
 95    ):
 96        (
 97            height,
 98            width,
 99            resized_height,
100            resized_width,
101        ) = generate_shape_and_resized_shape(
102            shapable_or_shape=shapable_or_shape,
103            resized_height=resized_height,
104            resized_width=resized_width
105        )
106        return Point.create(
107            y=resize_val(self.smooth_y, height, resized_height),
108            x=resize_val(self.smooth_x, width, resized_width),
109        )
class PointList(typing.List[vkit.element.point.Point]):
112class PointList(List[Point]):
113
114    ###############
115    # Constructor #
116    ###############
117    @classmethod
118    def from_point(cls, point: Point):
119        return cls((point,))
120
121    ##############
122    # Conversion #
123    ##############
124    @classmethod
125    def from_xy_pairs(cls, xy_pairs: Iterable[Tuple[_T, _T]]):
126        return cls(Point.from_xy_pair(xy_pair) for xy_pair in xy_pairs)
127
128    def to_xy_pairs(self):
129        return [point.to_xy_pair() for point in self]
130
131    def to_smooth_xy_pairs(self):
132        return [point.to_smooth_xy_pair() for point in self]
133
134    @classmethod
135    def from_flatten_xy_pairs(cls, flatten_xy_pairs: Sequence[_T]):
136        # [x0, y0, x1, y1, ...]
137        flatten_xy_pairs = tuple(flatten_xy_pairs)
138        assert flatten_xy_pairs and len(flatten_xy_pairs) % 2 == 0
139
140        points = PointList()
141        idx = 0
142        while idx < len(flatten_xy_pairs):
143            x = flatten_xy_pairs[idx]
144            y = flatten_xy_pairs[idx + 1]
145            points.append(Point.create(y=y, x=x))
146            idx += 2
147
148        return points
149
150    def to_flatten_xy_pairs(self):
151        return list(chain.from_iterable(point.to_xy_pair() for point in self))
152
153    def to_smooth_flatten_xy_pairs(self):
154        return list(chain.from_iterable(point.to_smooth_xy_pair() for point in self))
155
156    @classmethod
157    def from_np_array(cls, np_points: np.ndarray):
158        points = PointList()
159        for np_point in np_points:
160            x, y = np_point
161            points.append(Point.create(y=y, x=x))
162
163        if len(points) > 2 and points[0] == points[-1]:
164            # Handle the circled duplicated points generated by package like shapely.
165            points.pop()
166
167        return points
168
169    def to_np_array(self):
170        return np.asarray(self.to_xy_pairs(), dtype=np.int32)
171
172    def to_smooth_np_array(self):
173        return np.asarray(self.to_smooth_xy_pairs(), dtype=np.float32)
174
175    def to_point_tuple(self):
176        return PointTuple(self)
177
178    ############
179    # Operator #
180    ############
181    def copy(self):
182        return PointList(self)
183
184    def to_clipped_points(self, shapable_or_shape: Union[Shapable, Tuple[int, int]]):
185        return PointList(point.to_clipped_point(shapable_or_shape) for point in self)
186
187    def to_shifted_points(self, offset_y: int = 0, offset_x: int = 0):
188        return PointList(
189            point.to_shifted_point(
190                offset_y=offset_y,
191                offset_x=offset_x,
192            ) for point in self
193        )
194
195    def to_relative_points(self, origin_y: int, origin_x: int):
196        return self.to_shifted_points(offset_y=-origin_y, offset_x=-origin_x)
197
198    def to_conducted_resized_points(
199        self,
200        shapable_or_shape: Union[Shapable, Tuple[int, int]],
201        resized_height: Optional[int] = None,
202        resized_width: Optional[int] = None,
203    ):
204        return PointList(
205            point.to_conducted_resized_point(
206                shapable_or_shape=shapable_or_shape,
207                resized_height=resized_height,
208                resized_width=resized_width,
209            ) for point in self
210        )

Built-in mutable sequence.

If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.

@classmethod
def from_point(cls, point: vkit.element.point.Point):
117    @classmethod
118    def from_point(cls, point: Point):
119        return cls((point,))
@classmethod
def from_xy_pairs(cls, xy_pairs: Iterable[Tuple[Union[float, str], Union[float, str]]]):
124    @classmethod
125    def from_xy_pairs(cls, xy_pairs: Iterable[Tuple[_T, _T]]):
126        return cls(Point.from_xy_pair(xy_pair) for xy_pair in xy_pairs)
def to_xy_pairs(self):
128    def to_xy_pairs(self):
129        return [point.to_xy_pair() for point in self]
def to_smooth_xy_pairs(self):
131    def to_smooth_xy_pairs(self):
132        return [point.to_smooth_xy_pair() for point in self]
@classmethod
def from_flatten_xy_pairs(cls, flatten_xy_pairs: Sequence[Union[float, str]]):
134    @classmethod
135    def from_flatten_xy_pairs(cls, flatten_xy_pairs: Sequence[_T]):
136        # [x0, y0, x1, y1, ...]
137        flatten_xy_pairs = tuple(flatten_xy_pairs)
138        assert flatten_xy_pairs and len(flatten_xy_pairs) % 2 == 0
139
140        points = PointList()
141        idx = 0
142        while idx < len(flatten_xy_pairs):
143            x = flatten_xy_pairs[idx]
144            y = flatten_xy_pairs[idx + 1]
145            points.append(Point.create(y=y, x=x))
146            idx += 2
147
148        return points
def to_flatten_xy_pairs(self):
150    def to_flatten_xy_pairs(self):
151        return list(chain.from_iterable(point.to_xy_pair() for point in self))
def to_smooth_flatten_xy_pairs(self):
153    def to_smooth_flatten_xy_pairs(self):
154        return list(chain.from_iterable(point.to_smooth_xy_pair() for point in self))
@classmethod
def from_np_array(cls, np_points: numpy.ndarray):
156    @classmethod
157    def from_np_array(cls, np_points: np.ndarray):
158        points = PointList()
159        for np_point in np_points:
160            x, y = np_point
161            points.append(Point.create(y=y, x=x))
162
163        if len(points) > 2 and points[0] == points[-1]:
164            # Handle the circled duplicated points generated by package like shapely.
165            points.pop()
166
167        return points
def to_np_array(self):
169    def to_np_array(self):
170        return np.asarray(self.to_xy_pairs(), dtype=np.int32)
def to_smooth_np_array(self):
172    def to_smooth_np_array(self):
173        return np.asarray(self.to_smooth_xy_pairs(), dtype=np.float32)
def to_point_tuple(self):
175    def to_point_tuple(self):
176        return PointTuple(self)
def copy(self):
181    def copy(self):
182        return PointList(self)

Return a shallow copy of the list.

def to_clipped_points( self, shapable_or_shape: Union[vkit.element.type.Shapable, Tuple[int, int]]):
184    def to_clipped_points(self, shapable_or_shape: Union[Shapable, Tuple[int, int]]):
185        return PointList(point.to_clipped_point(shapable_or_shape) for point in self)
def to_shifted_points(self, offset_y: int = 0, offset_x: int = 0):
187    def to_shifted_points(self, offset_y: int = 0, offset_x: int = 0):
188        return PointList(
189            point.to_shifted_point(
190                offset_y=offset_y,
191                offset_x=offset_x,
192            ) for point in self
193        )
def to_relative_points(self, origin_y: int, origin_x: int):
195    def to_relative_points(self, origin_y: int, origin_x: int):
196        return self.to_shifted_points(offset_y=-origin_y, offset_x=-origin_x)
def to_conducted_resized_points( self, shapable_or_shape: Union[vkit.element.type.Shapable, Tuple[int, int]], resized_height: Union[int, NoneType] = None, resized_width: Union[int, NoneType] = None):
198    def to_conducted_resized_points(
199        self,
200        shapable_or_shape: Union[Shapable, Tuple[int, int]],
201        resized_height: Optional[int] = None,
202        resized_width: Optional[int] = None,
203    ):
204        return PointList(
205            point.to_conducted_resized_point(
206                shapable_or_shape=shapable_or_shape,
207                resized_height=resized_height,
208                resized_width=resized_width,
209            ) for point in self
210        )
Inherited Members
builtins.list
list
clear
append
insert
extend
pop
remove
index
count
reverse
sort
class PointTuple(typing.Tuple[vkit.element.point.Point, ...]):
213class PointTuple(Tuple[Point, ...]):
214
215    ###############
216    # Constructor #
217    ###############
218    @classmethod
219    def from_point(cls, point: Point):
220        return cls((point,))
221
222    ##############
223    # Conversion #
224    ##############
225    @classmethod
226    def from_xy_pairs(cls, xy_pairs: Iterable[Tuple[_T, _T]]):
227        return PointTuple(Point.from_xy_pair(xy_pair) for xy_pair in xy_pairs)
228
229    def to_xy_pairs(self):
230        return tuple(point.to_xy_pair() for point in self)
231
232    def to_smooth_xy_pairs(self):
233        return tuple(point.to_smooth_xy_pair() for point in self)
234
235    @classmethod
236    def from_flatten_xy_pairs(cls, flatten_xy_pairs: Sequence[_T]):
237        return PointList.from_flatten_xy_pairs(flatten_xy_pairs).to_point_tuple()
238
239    def to_flatten_xy_pairs(self):
240        return tuple(chain.from_iterable(point.to_xy_pair() for point in self))
241
242    def to_smooth_flatten_xy_pairs(self):
243        return tuple(chain.from_iterable(point.to_smooth_xy_pair() for point in self))
244
245    @classmethod
246    def from_np_array(cls, np_points: np.ndarray):
247        return PointList.from_np_array(np_points).to_point_tuple()
248
249    def to_np_array(self):
250        return np.asarray(self.to_xy_pairs(), dtype=np.int32)
251
252    def to_smooth_np_array(self):
253        return np.asarray(self.to_xy_pairs(), dtype=np.float32)
254
255    ############
256    # Operator #
257    ############
258    def to_clipped_points(self, shapable_or_shape: Union[Shapable, Tuple[int, int]]):
259        return PointTuple(point.to_clipped_point(shapable_or_shape) for point in self)
260
261    def to_shifted_points(self, offset_y: int = 0, offset_x: int = 0):
262        return PointTuple(
263            point.to_shifted_point(
264                offset_y=offset_y,
265                offset_x=offset_x,
266            ) for point in self
267        )
268
269    def to_relative_points(self, origin_y: int, origin_x: int):
270        return self.to_shifted_points(offset_y=-origin_y, offset_x=-origin_x)
271
272    def to_conducted_resized_points(
273        self,
274        shapable_or_shape: Union[Shapable, Tuple[int, int]],
275        resized_height: Optional[int] = None,
276        resized_width: Optional[int] = None,
277    ):
278        return PointTuple(
279            point.to_conducted_resized_point(
280                shapable_or_shape=shapable_or_shape,
281                resized_height=resized_height,
282                resized_width=resized_width,
283            ) for point in self
284        )

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

@classmethod
def from_point(cls, point: vkit.element.point.Point):
218    @classmethod
219    def from_point(cls, point: Point):
220        return cls((point,))
@classmethod
def from_xy_pairs(cls, xy_pairs: Iterable[Tuple[Union[float, str], Union[float, str]]]):
225    @classmethod
226    def from_xy_pairs(cls, xy_pairs: Iterable[Tuple[_T, _T]]):
227        return PointTuple(Point.from_xy_pair(xy_pair) for xy_pair in xy_pairs)
def to_xy_pairs(self):
229    def to_xy_pairs(self):
230        return tuple(point.to_xy_pair() for point in self)
def to_smooth_xy_pairs(self):
232    def to_smooth_xy_pairs(self):
233        return tuple(point.to_smooth_xy_pair() for point in self)
@classmethod
def from_flatten_xy_pairs(cls, flatten_xy_pairs: Sequence[Union[float, str]]):
235    @classmethod
236    def from_flatten_xy_pairs(cls, flatten_xy_pairs: Sequence[_T]):
237        return PointList.from_flatten_xy_pairs(flatten_xy_pairs).to_point_tuple()
def to_flatten_xy_pairs(self):
239    def to_flatten_xy_pairs(self):
240        return tuple(chain.from_iterable(point.to_xy_pair() for point in self))
def to_smooth_flatten_xy_pairs(self):
242    def to_smooth_flatten_xy_pairs(self):
243        return tuple(chain.from_iterable(point.to_smooth_xy_pair() for point in self))
@classmethod
def from_np_array(cls, np_points: numpy.ndarray):
245    @classmethod
246    def from_np_array(cls, np_points: np.ndarray):
247        return PointList.from_np_array(np_points).to_point_tuple()
def to_np_array(self):
249    def to_np_array(self):
250        return np.asarray(self.to_xy_pairs(), dtype=np.int32)
def to_smooth_np_array(self):
252    def to_smooth_np_array(self):
253        return np.asarray(self.to_xy_pairs(), dtype=np.float32)
def to_clipped_points( self, shapable_or_shape: Union[vkit.element.type.Shapable, Tuple[int, int]]):
258    def to_clipped_points(self, shapable_or_shape: Union[Shapable, Tuple[int, int]]):
259        return PointTuple(point.to_clipped_point(shapable_or_shape) for point in self)
def to_shifted_points(self, offset_y: int = 0, offset_x: int = 0):
261    def to_shifted_points(self, offset_y: int = 0, offset_x: int = 0):
262        return PointTuple(
263            point.to_shifted_point(
264                offset_y=offset_y,
265                offset_x=offset_x,
266            ) for point in self
267        )
def to_relative_points(self, origin_y: int, origin_x: int):
269    def to_relative_points(self, origin_y: int, origin_x: int):
270        return self.to_shifted_points(offset_y=-origin_y, offset_x=-origin_x)
def to_conducted_resized_points( self, shapable_or_shape: Union[vkit.element.type.Shapable, Tuple[int, int]], resized_height: Union[int, NoneType] = None, resized_width: Union[int, NoneType] = None):
272    def to_conducted_resized_points(
273        self,
274        shapable_or_shape: Union[Shapable, Tuple[int, int]],
275        resized_height: Optional[int] = None,
276        resized_width: Optional[int] = None,
277    ):
278        return PointTuple(
279            point.to_conducted_resized_point(
280                shapable_or_shape=shapable_or_shape,
281                resized_height=resized_height,
282                resized_width=resized_width,
283            ) for point in self
284        )
Inherited Members
builtins.tuple
index
count