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.
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: egeometry
3
- Version: 0.2.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,<0.2.0)
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.2.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 = "build.py"
9
+ script = "buildscript.py"
10
10
 
11
11
  [tool.poetry.dependencies]
12
12
  python = "^3.12"
13
- emath = "^0.1.10"
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,11 +0,0 @@
1
- from __future__ import annotations
2
-
3
- __all__ = [
4
- "DRectangle2d",
5
- "FRectangle2d",
6
- ]
7
-
8
-
9
- # egeometry
10
- from ._drectangle2d import DRectangle2d
11
- from ._frectangle2d import FRectangle2d
@@ -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