egeometry 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {egeometry-0.2.0 → egeometry-0.3.0}/PKG-INFO +2 -2
- {egeometry-0.2.0 → egeometry-0.3.0}/pyproject.toml +3 -3
- egeometry-0.3.0/src/egeometry/__init__.py +33 -0
- egeometry-0.3.0/src/egeometry/_dcircle.py +79 -0
- egeometry-0.3.0/src/egeometry/_drectangle.py +84 -0
- egeometry-0.3.0/src/egeometry/_fcircle.py +80 -0
- egeometry-0.3.0/src/egeometry/_frectangle.py +84 -0
- egeometry-0.3.0/src/egeometry/_icircle.py +80 -0
- egeometry-0.3.0/src/egeometry/_irectangle.py +84 -0
- egeometry-0.2.0/build.py +0 -20
- egeometry-0.2.0/src/egeometry/__init__.py +0 -11
- egeometry-0.2.0/src/egeometry/_drectangle2d.py +0 -40
- egeometry-0.2.0/src/egeometry/_frectangle2d.py +0 -40
- {egeometry-0.2.0 → egeometry-0.3.0}/src/egeometry/py.typed +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: egeometry
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Python geometry library.
|
|
5
5
|
Author: Erik Soma
|
|
6
6
|
Author-email: stillusingirc@gmail.com
|
|
7
7
|
Requires-Python: >=3.12,<4.0
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
-
Requires-Dist: emath (>=0.1.
|
|
10
|
+
Requires-Dist: emath (>=0.1.13,<0.2.0)
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "egeometry"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
description = "Python geometry library."
|
|
5
5
|
authors = ["Erik Soma <stillusingirc@gmail.com>"]
|
|
6
6
|
|
|
7
7
|
[tool.poetry.build]
|
|
8
8
|
generate-setup-file = false
|
|
9
|
-
script = "
|
|
9
|
+
script = "buildscript.py"
|
|
10
10
|
|
|
11
11
|
[tool.poetry.dependencies]
|
|
12
12
|
python = "^3.12"
|
|
13
|
-
emath = "^0.1.
|
|
13
|
+
emath = "^0.1.13"
|
|
14
14
|
|
|
15
15
|
[tool.poetry.group.dev.dependencies]
|
|
16
16
|
pytest = "7.4.3"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# generated from codegen/templates/__init__.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"DRectangle",
|
|
7
|
+
"DRectangleOverlappable",
|
|
8
|
+
"FRectangle",
|
|
9
|
+
"FRectangleOverlappable",
|
|
10
|
+
"IRectangle",
|
|
11
|
+
"IRectangleOverlappable",
|
|
12
|
+
"DCircle",
|
|
13
|
+
"DCircleOverlappable",
|
|
14
|
+
"FCircle",
|
|
15
|
+
"FCircleOverlappable",
|
|
16
|
+
"ICircle",
|
|
17
|
+
"ICircleOverlappable",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# egeometry
|
|
22
|
+
from ._dcircle import DCircle
|
|
23
|
+
from ._dcircle import DCircleOverlappable
|
|
24
|
+
from ._drectangle import DRectangle
|
|
25
|
+
from ._drectangle import DRectangleOverlappable
|
|
26
|
+
from ._fcircle import FCircle
|
|
27
|
+
from ._fcircle import FCircleOverlappable
|
|
28
|
+
from ._frectangle import FRectangle
|
|
29
|
+
from ._frectangle import FRectangleOverlappable
|
|
30
|
+
from ._icircle import ICircle
|
|
31
|
+
from ._icircle import ICircleOverlappable
|
|
32
|
+
from ._irectangle import IRectangle
|
|
33
|
+
from ._irectangle import IRectangleOverlappable
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# generated from codegen/templates/_circle.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = ["DCircle", "DCircleOverlappable"]
|
|
6
|
+
|
|
7
|
+
# egeometry
|
|
8
|
+
from ._drectangle import DRectangle
|
|
9
|
+
|
|
10
|
+
# emath
|
|
11
|
+
from emath import DVector2
|
|
12
|
+
|
|
13
|
+
# python
|
|
14
|
+
from typing import Protocol
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class DCircleOverlappable(Protocol):
|
|
18
|
+
def overlaps_d_circle(self, other: DCircle) -> bool:
|
|
19
|
+
...
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DCircle:
|
|
23
|
+
__slots__ = ["_bounding_box", "_position", "_radius"]
|
|
24
|
+
|
|
25
|
+
def __init__(self, position: DVector2, radius: float):
|
|
26
|
+
if radius <= 0:
|
|
27
|
+
raise ValueError("radius must be > 0")
|
|
28
|
+
self._position = position
|
|
29
|
+
self._radius = radius
|
|
30
|
+
self._bounding_box = DRectangle(position - radius, DVector2(radius * 2))
|
|
31
|
+
|
|
32
|
+
def __eq__(self, other: object) -> bool:
|
|
33
|
+
if not isinstance(other, DCircle):
|
|
34
|
+
return False
|
|
35
|
+
return self._position == other._position and self._radius == other._radius
|
|
36
|
+
|
|
37
|
+
def overlaps(self, other: DVector2 | DCircleOverlappable) -> bool:
|
|
38
|
+
if isinstance(other, DVector2):
|
|
39
|
+
return self.overlaps_d_vector_2(other)
|
|
40
|
+
try:
|
|
41
|
+
other_overlaps = other.overlaps_d_circle
|
|
42
|
+
except AttributeError:
|
|
43
|
+
raise TypeError(other)
|
|
44
|
+
return other_overlaps(self)
|
|
45
|
+
|
|
46
|
+
def overlaps_d_circle(self, other: DCircle) -> bool:
|
|
47
|
+
min_distance = self._radius + other._radius
|
|
48
|
+
distance = round(DVector2(*self._position).distance(DVector2(*other._position)))
|
|
49
|
+
return distance < min_distance
|
|
50
|
+
|
|
51
|
+
def overlaps_d_rectangle(self, other: DRectangle) -> bool:
|
|
52
|
+
rect_center = DVector2(*other.position) + (DVector2(*other.size) * 0.5)
|
|
53
|
+
f_position = DVector2(*self._position)
|
|
54
|
+
diff = f_position - rect_center
|
|
55
|
+
closest_rect_point = DVector2(
|
|
56
|
+
min(max(diff.x, other.position.x), other.extent.x),
|
|
57
|
+
min(max(diff.y, other.position.y), other.extent.y),
|
|
58
|
+
)
|
|
59
|
+
closest_rect_point_distance = round(f_position.distance(closest_rect_point))
|
|
60
|
+
return closest_rect_point_distance < self._radius
|
|
61
|
+
|
|
62
|
+
def overlaps_d_vector_2(self, other: DVector2) -> bool:
|
|
63
|
+
distance = round(DVector2(*self._position).distance(DVector2(*other)))
|
|
64
|
+
return distance < self._radius
|
|
65
|
+
|
|
66
|
+
def translate(self, translation: DVector2) -> DCircle:
|
|
67
|
+
return DCircle(self._position + translation, self._radius)
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def bounding_box(self) -> DRectangle:
|
|
71
|
+
return self._bounding_box
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def position(self) -> DVector2:
|
|
75
|
+
return self._position
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def radius(self) -> float:
|
|
79
|
+
return self._radius
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# generated from codegen/templates/_rectangle.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = ["DRectangle", "DRectangleOverlappable"]
|
|
6
|
+
|
|
7
|
+
# emath
|
|
8
|
+
from emath import DVector2
|
|
9
|
+
|
|
10
|
+
# python
|
|
11
|
+
from typing import Protocol
|
|
12
|
+
from typing import TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
# egeometry
|
|
16
|
+
from ._dcircle import DCircle
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class DRectangleOverlappable(Protocol):
|
|
20
|
+
def overlaps_d_rectangle(self, other: DRectangle) -> bool:
|
|
21
|
+
...
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class DRectangle:
|
|
25
|
+
__slots__ = ["_extent", "_position", "_size"]
|
|
26
|
+
|
|
27
|
+
def __init__(self, position: DVector2, size: DVector2):
|
|
28
|
+
if size <= DVector2(0):
|
|
29
|
+
raise ValueError("each size dimension must be > 0")
|
|
30
|
+
self._position = position
|
|
31
|
+
self._size = size
|
|
32
|
+
self._extent = self._position + self._size
|
|
33
|
+
|
|
34
|
+
def __eq__(self, other: object) -> bool:
|
|
35
|
+
if not isinstance(other, DRectangle):
|
|
36
|
+
return False
|
|
37
|
+
return self._position == other._position and self._size == other._size
|
|
38
|
+
|
|
39
|
+
def overlaps(self, other: DVector2 | DRectangleOverlappable) -> bool:
|
|
40
|
+
if isinstance(other, DVector2):
|
|
41
|
+
return self.overlaps_d_vector_2(other)
|
|
42
|
+
try:
|
|
43
|
+
other_overlaps = other.overlaps_d_rectangle
|
|
44
|
+
except AttributeError:
|
|
45
|
+
raise TypeError(other)
|
|
46
|
+
return other_overlaps(self)
|
|
47
|
+
|
|
48
|
+
def overlaps_d_circle(self, other: DCircle) -> bool:
|
|
49
|
+
return other.overlaps_d_rectangle(self)
|
|
50
|
+
|
|
51
|
+
def overlaps_d_rectangle(self, other: DRectangle) -> bool:
|
|
52
|
+
return not (
|
|
53
|
+
self._position.x >= other._extent.x
|
|
54
|
+
or self._extent.x <= other._position.x
|
|
55
|
+
or self._position.y >= other._extent.y
|
|
56
|
+
or self._extent.y <= other._position.y
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def overlaps_d_vector_2(self, other: DVector2) -> bool:
|
|
60
|
+
return (
|
|
61
|
+
other.x >= self._position.x
|
|
62
|
+
and other.x < self._extent.x
|
|
63
|
+
and other.y >= self._position.y
|
|
64
|
+
and other.y < self._extent.y
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def translate(self, translation: DVector2) -> DRectangle:
|
|
68
|
+
return DRectangle(self._position + translation, self._size)
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def bounding_box(self) -> DRectangle:
|
|
72
|
+
return self
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def extent(self) -> DVector2:
|
|
76
|
+
return self._extent
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def position(self) -> DVector2:
|
|
80
|
+
return self._position
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def size(self) -> DVector2:
|
|
84
|
+
return self._size
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# generated from codegen/templates/_circle.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = ["FCircle", "FCircleOverlappable"]
|
|
6
|
+
|
|
7
|
+
# egeometry
|
|
8
|
+
from ._frectangle import FRectangle
|
|
9
|
+
|
|
10
|
+
# emath
|
|
11
|
+
from emath import DVector2
|
|
12
|
+
from emath import FVector2
|
|
13
|
+
|
|
14
|
+
# python
|
|
15
|
+
from typing import Protocol
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class FCircleOverlappable(Protocol):
|
|
19
|
+
def overlaps_f_circle(self, other: FCircle) -> bool:
|
|
20
|
+
...
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class FCircle:
|
|
24
|
+
__slots__ = ["_bounding_box", "_position", "_radius"]
|
|
25
|
+
|
|
26
|
+
def __init__(self, position: FVector2, radius: float):
|
|
27
|
+
if radius <= 0:
|
|
28
|
+
raise ValueError("radius must be > 0")
|
|
29
|
+
self._position = position
|
|
30
|
+
self._radius = radius
|
|
31
|
+
self._bounding_box = FRectangle(position - radius, FVector2(radius * 2))
|
|
32
|
+
|
|
33
|
+
def __eq__(self, other: object) -> bool:
|
|
34
|
+
if not isinstance(other, FCircle):
|
|
35
|
+
return False
|
|
36
|
+
return self._position == other._position and self._radius == other._radius
|
|
37
|
+
|
|
38
|
+
def overlaps(self, other: FVector2 | FCircleOverlappable) -> bool:
|
|
39
|
+
if isinstance(other, FVector2):
|
|
40
|
+
return self.overlaps_f_vector_2(other)
|
|
41
|
+
try:
|
|
42
|
+
other_overlaps = other.overlaps_f_circle
|
|
43
|
+
except AttributeError:
|
|
44
|
+
raise TypeError(other)
|
|
45
|
+
return other_overlaps(self)
|
|
46
|
+
|
|
47
|
+
def overlaps_f_circle(self, other: FCircle) -> bool:
|
|
48
|
+
min_distance = self._radius + other._radius
|
|
49
|
+
distance = round(DVector2(*self._position).distance(DVector2(*other._position)))
|
|
50
|
+
return distance < min_distance
|
|
51
|
+
|
|
52
|
+
def overlaps_f_rectangle(self, other: FRectangle) -> bool:
|
|
53
|
+
rect_center = DVector2(*other.position) + (DVector2(*other.size) * 0.5)
|
|
54
|
+
f_position = DVector2(*self._position)
|
|
55
|
+
diff = f_position - rect_center
|
|
56
|
+
closest_rect_point = DVector2(
|
|
57
|
+
min(max(diff.x, other.position.x), other.extent.x),
|
|
58
|
+
min(max(diff.y, other.position.y), other.extent.y),
|
|
59
|
+
)
|
|
60
|
+
closest_rect_point_distance = round(f_position.distance(closest_rect_point))
|
|
61
|
+
return closest_rect_point_distance < self._radius
|
|
62
|
+
|
|
63
|
+
def overlaps_f_vector_2(self, other: FVector2) -> bool:
|
|
64
|
+
distance = round(DVector2(*self._position).distance(DVector2(*other)))
|
|
65
|
+
return distance < self._radius
|
|
66
|
+
|
|
67
|
+
def translate(self, translation: FVector2) -> FCircle:
|
|
68
|
+
return FCircle(self._position + translation, self._radius)
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def bounding_box(self) -> FRectangle:
|
|
72
|
+
return self._bounding_box
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def position(self) -> FVector2:
|
|
76
|
+
return self._position
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def radius(self) -> float:
|
|
80
|
+
return self._radius
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# generated from codegen/templates/_rectangle.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = ["FRectangle", "FRectangleOverlappable"]
|
|
6
|
+
|
|
7
|
+
# emath
|
|
8
|
+
from emath import FVector2
|
|
9
|
+
|
|
10
|
+
# python
|
|
11
|
+
from typing import Protocol
|
|
12
|
+
from typing import TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
# egeometry
|
|
16
|
+
from ._fcircle import FCircle
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class FRectangleOverlappable(Protocol):
|
|
20
|
+
def overlaps_f_rectangle(self, other: FRectangle) -> bool:
|
|
21
|
+
...
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class FRectangle:
|
|
25
|
+
__slots__ = ["_extent", "_position", "_size"]
|
|
26
|
+
|
|
27
|
+
def __init__(self, position: FVector2, size: FVector2):
|
|
28
|
+
if size <= FVector2(0):
|
|
29
|
+
raise ValueError("each size dimension must be > 0")
|
|
30
|
+
self._position = position
|
|
31
|
+
self._size = size
|
|
32
|
+
self._extent = self._position + self._size
|
|
33
|
+
|
|
34
|
+
def __eq__(self, other: object) -> bool:
|
|
35
|
+
if not isinstance(other, FRectangle):
|
|
36
|
+
return False
|
|
37
|
+
return self._position == other._position and self._size == other._size
|
|
38
|
+
|
|
39
|
+
def overlaps(self, other: FVector2 | FRectangleOverlappable) -> bool:
|
|
40
|
+
if isinstance(other, FVector2):
|
|
41
|
+
return self.overlaps_f_vector_2(other)
|
|
42
|
+
try:
|
|
43
|
+
other_overlaps = other.overlaps_f_rectangle
|
|
44
|
+
except AttributeError:
|
|
45
|
+
raise TypeError(other)
|
|
46
|
+
return other_overlaps(self)
|
|
47
|
+
|
|
48
|
+
def overlaps_f_circle(self, other: FCircle) -> bool:
|
|
49
|
+
return other.overlaps_f_rectangle(self)
|
|
50
|
+
|
|
51
|
+
def overlaps_f_rectangle(self, other: FRectangle) -> bool:
|
|
52
|
+
return not (
|
|
53
|
+
self._position.x >= other._extent.x
|
|
54
|
+
or self._extent.x <= other._position.x
|
|
55
|
+
or self._position.y >= other._extent.y
|
|
56
|
+
or self._extent.y <= other._position.y
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def overlaps_f_vector_2(self, other: FVector2) -> bool:
|
|
60
|
+
return (
|
|
61
|
+
other.x >= self._position.x
|
|
62
|
+
and other.x < self._extent.x
|
|
63
|
+
and other.y >= self._position.y
|
|
64
|
+
and other.y < self._extent.y
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def translate(self, translation: FVector2) -> FRectangle:
|
|
68
|
+
return FRectangle(self._position + translation, self._size)
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def bounding_box(self) -> FRectangle:
|
|
72
|
+
return self
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def extent(self) -> FVector2:
|
|
76
|
+
return self._extent
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def position(self) -> FVector2:
|
|
80
|
+
return self._position
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def size(self) -> FVector2:
|
|
84
|
+
return self._size
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# generated from codegen/templates/_circle.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = ["ICircle", "ICircleOverlappable"]
|
|
6
|
+
|
|
7
|
+
# egeometry
|
|
8
|
+
from ._irectangle import IRectangle
|
|
9
|
+
|
|
10
|
+
# emath
|
|
11
|
+
from emath import DVector2
|
|
12
|
+
from emath import IVector2
|
|
13
|
+
|
|
14
|
+
# python
|
|
15
|
+
from typing import Protocol
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ICircleOverlappable(Protocol):
|
|
19
|
+
def overlaps_i_circle(self, other: ICircle) -> bool:
|
|
20
|
+
...
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ICircle:
|
|
24
|
+
__slots__ = ["_bounding_box", "_position", "_radius"]
|
|
25
|
+
|
|
26
|
+
def __init__(self, position: IVector2, radius: int):
|
|
27
|
+
if radius <= 0:
|
|
28
|
+
raise ValueError("radius must be > 0")
|
|
29
|
+
self._position = position
|
|
30
|
+
self._radius = radius
|
|
31
|
+
self._bounding_box = IRectangle(position - radius, IVector2(radius * 2))
|
|
32
|
+
|
|
33
|
+
def __eq__(self, other: object) -> bool:
|
|
34
|
+
if not isinstance(other, ICircle):
|
|
35
|
+
return False
|
|
36
|
+
return self._position == other._position and self._radius == other._radius
|
|
37
|
+
|
|
38
|
+
def overlaps(self, other: IVector2 | ICircleOverlappable) -> bool:
|
|
39
|
+
if isinstance(other, IVector2):
|
|
40
|
+
return self.overlaps_i_vector_2(other)
|
|
41
|
+
try:
|
|
42
|
+
other_overlaps = other.overlaps_i_circle
|
|
43
|
+
except AttributeError:
|
|
44
|
+
raise TypeError(other)
|
|
45
|
+
return other_overlaps(self)
|
|
46
|
+
|
|
47
|
+
def overlaps_i_circle(self, other: ICircle) -> bool:
|
|
48
|
+
min_distance = self._radius + other._radius
|
|
49
|
+
distance = round(DVector2(*self._position).distance(DVector2(*other._position)))
|
|
50
|
+
return distance < min_distance
|
|
51
|
+
|
|
52
|
+
def overlaps_i_rectangle(self, other: IRectangle) -> bool:
|
|
53
|
+
rect_center = DVector2(*other.position) + (DVector2(*other.size) * 0.5)
|
|
54
|
+
f_position = DVector2(*self._position)
|
|
55
|
+
diff = f_position - rect_center
|
|
56
|
+
closest_rect_point = DVector2(
|
|
57
|
+
min(max(diff.x, other.position.x), other.extent.x),
|
|
58
|
+
min(max(diff.y, other.position.y), other.extent.y),
|
|
59
|
+
)
|
|
60
|
+
closest_rect_point_distance = round(f_position.distance(closest_rect_point))
|
|
61
|
+
return closest_rect_point_distance < self._radius
|
|
62
|
+
|
|
63
|
+
def overlaps_i_vector_2(self, other: IVector2) -> bool:
|
|
64
|
+
distance = round(DVector2(*self._position).distance(DVector2(*other)))
|
|
65
|
+
return distance < self._radius
|
|
66
|
+
|
|
67
|
+
def translate(self, translation: IVector2) -> ICircle:
|
|
68
|
+
return ICircle(self._position + translation, self._radius)
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def bounding_box(self) -> IRectangle:
|
|
72
|
+
return self._bounding_box
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def position(self) -> IVector2:
|
|
76
|
+
return self._position
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def radius(self) -> int:
|
|
80
|
+
return self._radius
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# generated from codegen/templates/_rectangle.py
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = ["IRectangle", "IRectangleOverlappable"]
|
|
6
|
+
|
|
7
|
+
# emath
|
|
8
|
+
from emath import IVector2
|
|
9
|
+
|
|
10
|
+
# python
|
|
11
|
+
from typing import Protocol
|
|
12
|
+
from typing import TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
# egeometry
|
|
16
|
+
from ._icircle import ICircle
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class IRectangleOverlappable(Protocol):
|
|
20
|
+
def overlaps_i_rectangle(self, other: IRectangle) -> bool:
|
|
21
|
+
...
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class IRectangle:
|
|
25
|
+
__slots__ = ["_extent", "_position", "_size"]
|
|
26
|
+
|
|
27
|
+
def __init__(self, position: IVector2, size: IVector2):
|
|
28
|
+
if size <= IVector2(0):
|
|
29
|
+
raise ValueError("each size dimension must be > 0")
|
|
30
|
+
self._position = position
|
|
31
|
+
self._size = size
|
|
32
|
+
self._extent = self._position + self._size
|
|
33
|
+
|
|
34
|
+
def __eq__(self, other: object) -> bool:
|
|
35
|
+
if not isinstance(other, IRectangle):
|
|
36
|
+
return False
|
|
37
|
+
return self._position == other._position and self._size == other._size
|
|
38
|
+
|
|
39
|
+
def overlaps(self, other: IVector2 | IRectangleOverlappable) -> bool:
|
|
40
|
+
if isinstance(other, IVector2):
|
|
41
|
+
return self.overlaps_i_vector_2(other)
|
|
42
|
+
try:
|
|
43
|
+
other_overlaps = other.overlaps_i_rectangle
|
|
44
|
+
except AttributeError:
|
|
45
|
+
raise TypeError(other)
|
|
46
|
+
return other_overlaps(self)
|
|
47
|
+
|
|
48
|
+
def overlaps_i_circle(self, other: ICircle) -> bool:
|
|
49
|
+
return other.overlaps_i_rectangle(self)
|
|
50
|
+
|
|
51
|
+
def overlaps_i_rectangle(self, other: IRectangle) -> bool:
|
|
52
|
+
return not (
|
|
53
|
+
self._position.x >= other._extent.x
|
|
54
|
+
or self._extent.x <= other._position.x
|
|
55
|
+
or self._position.y >= other._extent.y
|
|
56
|
+
or self._extent.y <= other._position.y
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def overlaps_i_vector_2(self, other: IVector2) -> bool:
|
|
60
|
+
return (
|
|
61
|
+
other.x >= self._position.x
|
|
62
|
+
and other.x < self._extent.x
|
|
63
|
+
and other.y >= self._position.y
|
|
64
|
+
and other.y < self._extent.y
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def translate(self, translation: IVector2) -> IRectangle:
|
|
68
|
+
return IRectangle(self._position + translation, self._size)
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def bounding_box(self) -> IRectangle:
|
|
72
|
+
return self
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def extent(self) -> IVector2:
|
|
76
|
+
return self._extent
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def position(self) -> IVector2:
|
|
80
|
+
return self._position
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def size(self) -> IVector2:
|
|
84
|
+
return self._size
|
egeometry-0.2.0/build.py
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
__all__ = ()
|
|
4
|
-
|
|
5
|
-
# egeometry
|
|
6
|
-
# codegen
|
|
7
|
-
from codegen import generate_geometry_files
|
|
8
|
-
|
|
9
|
-
# python
|
|
10
|
-
import os
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def _build() -> None:
|
|
15
|
-
if os.environ.get("EGEOMETRY_GENERATE_GEOMETRY_FILES", "1") == "1":
|
|
16
|
-
generate_geometry_files(Path("src/egeometry"))
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if __name__ == "__main__":
|
|
20
|
-
_build()
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# generated from codegen/templates/_rectangle_2d.cpp
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
__all__ = ["DRectangle2d"]
|
|
6
|
-
|
|
7
|
-
# emath
|
|
8
|
-
from emath import DVector2
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class DRectangle2d:
|
|
12
|
-
__slots__ = ["_extent", "_position", "_size"]
|
|
13
|
-
|
|
14
|
-
def __init__(self, position: DVector2, size: DVector2):
|
|
15
|
-
if size <= DVector2(0):
|
|
16
|
-
raise ValueError("each size dimension must be > 0")
|
|
17
|
-
self._position = position
|
|
18
|
-
self._size = size
|
|
19
|
-
self._extent = self._position + self._size
|
|
20
|
-
|
|
21
|
-
def __eq__(self, other: object) -> bool:
|
|
22
|
-
if not isinstance(other, DRectangle2d):
|
|
23
|
-
return False
|
|
24
|
-
return self._position == other._position and self._size == other._size
|
|
25
|
-
|
|
26
|
-
@property
|
|
27
|
-
def bounding_box(self) -> DRectangle2d:
|
|
28
|
-
return self
|
|
29
|
-
|
|
30
|
-
@property
|
|
31
|
-
def extent(self) -> DVector2:
|
|
32
|
-
return self._extent
|
|
33
|
-
|
|
34
|
-
@property
|
|
35
|
-
def position(self) -> DVector2:
|
|
36
|
-
return self._position
|
|
37
|
-
|
|
38
|
-
@property
|
|
39
|
-
def size(self) -> DVector2:
|
|
40
|
-
return self._size
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# generated from codegen/templates/_rectangle_2d.cpp
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
__all__ = ["FRectangle2d"]
|
|
6
|
-
|
|
7
|
-
# emath
|
|
8
|
-
from emath import FVector2
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class FRectangle2d:
|
|
12
|
-
__slots__ = ["_extent", "_position", "_size"]
|
|
13
|
-
|
|
14
|
-
def __init__(self, position: FVector2, size: FVector2):
|
|
15
|
-
if size <= FVector2(0):
|
|
16
|
-
raise ValueError("each size dimension must be > 0")
|
|
17
|
-
self._position = position
|
|
18
|
-
self._size = size
|
|
19
|
-
self._extent = self._position + self._size
|
|
20
|
-
|
|
21
|
-
def __eq__(self, other: object) -> bool:
|
|
22
|
-
if not isinstance(other, FRectangle2d):
|
|
23
|
-
return False
|
|
24
|
-
return self._position == other._position and self._size == other._size
|
|
25
|
-
|
|
26
|
-
@property
|
|
27
|
-
def bounding_box(self) -> FRectangle2d:
|
|
28
|
-
return self
|
|
29
|
-
|
|
30
|
-
@property
|
|
31
|
-
def extent(self) -> FVector2:
|
|
32
|
-
return self._extent
|
|
33
|
-
|
|
34
|
-
@property
|
|
35
|
-
def position(self) -> FVector2:
|
|
36
|
-
return self._position
|
|
37
|
-
|
|
38
|
-
@property
|
|
39
|
-
def size(self) -> FVector2:
|
|
40
|
-
return self._size
|
|
File without changes
|