pode 0.4.3__tar.gz → 0.4.7__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,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2019 Georgy Skorobogatov
3
+ Copyright (c) 2026, Georgy Skorobogatov
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
+
pode-0.4.7/PKG-INFO ADDED
@@ -0,0 +1,261 @@
1
+ Metadata-Version: 2.4
2
+ Name: pode
3
+ Version: 0.4.7
4
+ Summary: Implementation the polygon decomposition algorithm by Hert, S. and Lumelsky, V., 1998
5
+ License-File: LICENSE
6
+ Author: Georgy Skorobogatov
7
+ Author-email: skorobogatovgeorgy+github@gmail.com
8
+ Requires-Python: >=3.11,!=3.14.1,<4.0
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Classifier: Programming Language :: Python :: 3.14
14
+ Classifier: Programming Language :: Python :: 3.15
15
+ Requires-Dist: gon (>=5.0.0,<6.0.0)
16
+ Requires-Dist: ground (>=8.1.0,<9.0.0)
17
+ Requires-Dist: networkx (>=3.6.1,<4.0.0)
18
+ Requires-Dist: sect (>=6.1.0,<7.0.0)
19
+ Description-Content-Type: text/markdown
20
+
21
+ pode
22
+ ===
23
+
24
+ [![](https://github.com/GeorgySk/pode/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/GeorgySk/pode/actions/workflows/ci.yml?query=branch%3Amain "GitHub Actions")
25
+ [![](https://codecov.io/gh/GeorgySk/pode/branch/main/graph/badge.svg)](https://codecov.io/gh/GeorgySk/pode "Codecov")
26
+ [![](https://readthedocs.org/projects/pode/badge/?version=latest)](https://pode.readthedocs.io/en/latest "Documentation")
27
+ [![](https://img.shields.io/github/license/GeorgySk/pode.svg)](https://github.com/GeorgySk/pode/blob/main/LICENSE "License")
28
+ [![](https://badge.fury.io/py/pode.svg)](https://badge.fury.io/py/pode "PyPI")
29
+ [![](https://img.shields.io/pypi/pyversions/pode.svg)](https://pypi.org/project/pode "Supported Python versions")
30
+ [![](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-orange.json)](https://github.com/GeorgySk/copier-pypackage "Generated from the copier-pypackage template")
31
+
32
+ Summary
33
+ -------
34
+
35
+ Pode is a Python library that implements an algorithm of
36
+ [Hert, S. and Lumelsky, V., 1998](https://www.worldscientific.com/doi/abs/10.1142/S0218195998000230)
37
+ for a polygon decomposition into separate parts depending on the area
38
+ requirements.
39
+
40
+ Main features are
41
+ - all calculations are robust for floating point numbers
42
+ & precise for integral numbers (like `int`);
43
+ - support for partition of convex/nonconvex polygons with/without holes;
44
+ - support for anchored partition, free partition, and a mixture of both
45
+ where anchored polygon partition requires the resulting polygon parts
46
+ to contain specified points called "anchors" or "sites", and free
47
+ partition does not have any constraints on the resulting geometries;
48
+ - most of the code is covered with property-based tests.
49
+
50
+ ---
51
+
52
+ In what follows, `python` is an alias for `python3.11`
53
+ or any later version.
54
+
55
+ Installation
56
+ ------------
57
+
58
+ Install the latest `pip` & `setuptools` packages versions
59
+ ```bash
60
+ python -m pip install --upgrade pip setuptools
61
+ ```
62
+
63
+ ### User
64
+
65
+ Download and install the latest stable version from `PyPI` repository
66
+ ```bash
67
+ python -m pip install --upgrade pode
68
+ ```
69
+
70
+ ### Developer
71
+
72
+ Download the latest version from `GitHub` repository
73
+ ```bash
74
+ git clone https://github.com/GeorgySk/pode.git
75
+ cd pode
76
+ ```
77
+
78
+ Install
79
+ ```bash
80
+ poetry install
81
+ ```
82
+
83
+ Usage
84
+ -----
85
+
86
+ ```python
87
+ >>> from pode import divide, Contour, Point, Polygon, Requirement
88
+ >>> contour = Contour([Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)])
89
+ >>> polygon = Polygon(contour)
90
+ >>> requirements = [Requirement(0.5), Requirement(0.5, point=Point(1, 1))]
91
+ >>> parts = divide(polygon, requirements)
92
+ >>> parts[0].area == parts[1].area < polygon.area
93
+ True
94
+ >>> Point(1, 1) in parts[1]
95
+ True
96
+
97
+ ```
98
+ Currently, the algorithm uses constrained Delaunay triangulation to form convex
99
+ parts which are used internally for a convex-polygon partition.
100
+ This triangulation, however, affects the resulting partition. The resulting
101
+ parts can have zigzag pattern separating different parts. In this way, the
102
+ solution can be far from being optimal in sense of the number of sides of the
103
+ resulting polygons. Alternatively, we implemented a helper function that would
104
+ join neighboring triangles if they form a larger convex part. It can be
105
+ imported as `from pode import joined_constrained_delaunay_triangles` and used
106
+ as `divide(polygon, requirements, joined_constrained_delaunay_triangles)`. But,
107
+ in the future, a better algorithm should be implemented, like
108
+ [Greene, D.H., 1983](https://www.goodreads.com/book/show/477772.Advances_in_Computing_Research_Volume_1)
109
+ or [Chazelle, B. and Dobkin, D., 1979](https://dl.acm.org/doi/abs/10.1145/800135.804396).
110
+
111
+ Development
112
+ -----------
113
+
114
+ ### Bumping version
115
+
116
+ #### Preparation
117
+
118
+ Install
119
+ [bump-my-version](https://github.com/callowayproject/bump-my-version/tree/master?tab=readme-ov-file#installation).
120
+
121
+ #### Pre-release
122
+
123
+ Choose which version number category to bump following [semver
124
+ specification](http://semver.org/).
125
+
126
+ Test bumping version
127
+ ```bash
128
+ bump-my-version bump --dry-run --verbose $CATEGORY
129
+ ```
130
+
131
+ where `$CATEGORY` is the target version number category name, possible
132
+ values are `patch`/`minor`/`major`.
133
+
134
+ Bump version
135
+ ```bash
136
+ bump-my-version bump --verbose $CATEGORY
137
+ ```
138
+
139
+ This will set version to `major.minor.patch-alpha`.
140
+
141
+ #### Release
142
+
143
+ Test bumping version
144
+ ```bash
145
+ bump-my-version bump --dry-run --verbose release
146
+ ```
147
+
148
+ Bump version
149
+ ```bash
150
+ bump-my-version bump --verbose release
151
+ ```
152
+
153
+ This will set version to `major.minor.patch`.
154
+
155
+ ### Publishing
156
+
157
+ Pushing a final release tag `vX.Y.Z` runs the CI publish jobs, which upload
158
+ the package to PyPI and push
159
+ the `prod` Docker image to the GitHub container registry (GHCR).
160
+ Pre-release tags such as `vX.Y.Z-alpha` are not published.
161
+
162
+ `bump-my-version bump release` commits and tags the release, so push both:
163
+ ```bash
164
+ git push --follow-tags
165
+ ```
166
+
167
+ One-time setup:
168
+
169
+ - GitHub: on PyPI, add a
170
+ [Trusted Publisher](https://docs.pypi.org/trusted-publishers/adding-a-publisher/)
171
+ for this repository with workflow `ci.yml` and environment `pypi`.
172
+ - GitHub: add a `CODECOV_TOKEN` repository secret from
173
+ [Codecov](https://codecov.io/).
174
+
175
+ ### Linting, formatting and type checking
176
+
177
+ [Ruff](https://docs.astral.sh/ruff/) is used for linting
178
+ (installed with the `dev` dependency group).
179
+
180
+ Check code
181
+ ```bash
182
+ ruff check .
183
+ ```
184
+
185
+ Fix automatically fixable issues
186
+ ```bash
187
+ ruff check --fix .
188
+ ```
189
+
190
+ [mypy](https://mypy.readthedocs.io/) checks types in strict mode
191
+ (configured in `pyproject.toml`)
192
+ ```bash
193
+ mypy .
194
+ ```
195
+
196
+ The package ships a `py.typed` marker, so projects that use it get its type
197
+ hints too.
198
+
199
+ To run these checks (Ruff and mypy) automatically on each commit,
200
+ install the [pre-commit](https://pre-commit.com/) hooks
201
+ (once, after the repository has been initialized with `git init`)
202
+ ```bash
203
+ pre-commit install
204
+ ```
205
+
206
+ ### Running tests
207
+
208
+ Install the project with the `dev` dependency group (pytest, pytest-cov,
209
+ Hypothesis)
210
+ ```bash
211
+ poetry install --with dev
212
+ ```
213
+
214
+ Run the tests
215
+ ```bash
216
+ poetry run pytest
217
+ ```
218
+
219
+ Run the tests with a coverage report, as CI does
220
+ ```bash
221
+ poetry run pytest --cov --cov-report=term
222
+ ```
223
+
224
+ Inside the dev container, dependencies are already installed into the
225
+ container's Python, so `poetry run` can be dropped: `pytest`.
226
+
227
+ Inside a `Docker` container (the default `IMAGE_TYPE=dev` image includes the
228
+ `dev` group)
229
+ ```bash
230
+ docker compose run --rm --entrypoint pytest pode
231
+ ```
232
+
233
+ ### Updating from the template
234
+
235
+ This project was generated from the
236
+ [copier-pypackage](https://github.com/GeorgySk/copier-pypackage) template.
237
+ To pull in a newer release of the template (CI, tooling and configuration
238
+ fixes), commit your changes, then run
239
+ ```bash
240
+ copier update --defaults
241
+ ```
242
+ Copier merges the template's changes into the project and keeps yours.
243
+ Review them with `git diff`, resolve any conflict markers and commit.
244
+ `CHANGES.rst` and `pode/__init__.py` are never touched by
245
+ updates, and `.copier-answers.yml` must not be edited by hand.
246
+
247
+ The `Template update` workflow (`.github/workflows/template-update.yml`) does
248
+ this every Monday and opens a pull request when there is a new template
249
+ release (run it by hand from the Actions tab). Conflicting changes are
250
+ committed with conflict markers in a draft pull request: resolve them on its
251
+ branch. There is one pull request per release, so closing one skips that
252
+ release. The template must be at a URL GitHub can clone (the `_src_path` in
253
+ `.copier-answers.yml`).
254
+
255
+ With the default `GITHUB_TOKEN`, enable "Allow GitHub Actions to create and
256
+ approve pull requests" (Settings → Actions → General). Even then the pull
257
+ request doesn't run CI, and updates that change `.github/workflows` can't be
258
+ pushed. To avoid both, add a `TEMPLATE_UPDATE_TOKEN` repository secret: a
259
+ fine-grained personal access token for this repository with read and write
260
+ access to Contents, Pull requests and Workflows.
261
+
pode-0.4.7/README.md ADDED
@@ -0,0 +1,240 @@
1
+ pode
2
+ ===
3
+
4
+ [![](https://github.com/GeorgySk/pode/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/GeorgySk/pode/actions/workflows/ci.yml?query=branch%3Amain "GitHub Actions")
5
+ [![](https://codecov.io/gh/GeorgySk/pode/branch/main/graph/badge.svg)](https://codecov.io/gh/GeorgySk/pode "Codecov")
6
+ [![](https://readthedocs.org/projects/pode/badge/?version=latest)](https://pode.readthedocs.io/en/latest "Documentation")
7
+ [![](https://img.shields.io/github/license/GeorgySk/pode.svg)](https://github.com/GeorgySk/pode/blob/main/LICENSE "License")
8
+ [![](https://badge.fury.io/py/pode.svg)](https://badge.fury.io/py/pode "PyPI")
9
+ [![](https://img.shields.io/pypi/pyversions/pode.svg)](https://pypi.org/project/pode "Supported Python versions")
10
+ [![](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-orange.json)](https://github.com/GeorgySk/copier-pypackage "Generated from the copier-pypackage template")
11
+
12
+ Summary
13
+ -------
14
+
15
+ Pode is a Python library that implements an algorithm of
16
+ [Hert, S. and Lumelsky, V., 1998](https://www.worldscientific.com/doi/abs/10.1142/S0218195998000230)
17
+ for a polygon decomposition into separate parts depending on the area
18
+ requirements.
19
+
20
+ Main features are
21
+ - all calculations are robust for floating point numbers
22
+ & precise for integral numbers (like `int`);
23
+ - support for partition of convex/nonconvex polygons with/without holes;
24
+ - support for anchored partition, free partition, and a mixture of both
25
+ where anchored polygon partition requires the resulting polygon parts
26
+ to contain specified points called "anchors" or "sites", and free
27
+ partition does not have any constraints on the resulting geometries;
28
+ - most of the code is covered with property-based tests.
29
+
30
+ ---
31
+
32
+ In what follows, `python` is an alias for `python3.11`
33
+ or any later version.
34
+
35
+ Installation
36
+ ------------
37
+
38
+ Install the latest `pip` & `setuptools` packages versions
39
+ ```bash
40
+ python -m pip install --upgrade pip setuptools
41
+ ```
42
+
43
+ ### User
44
+
45
+ Download and install the latest stable version from `PyPI` repository
46
+ ```bash
47
+ python -m pip install --upgrade pode
48
+ ```
49
+
50
+ ### Developer
51
+
52
+ Download the latest version from `GitHub` repository
53
+ ```bash
54
+ git clone https://github.com/GeorgySk/pode.git
55
+ cd pode
56
+ ```
57
+
58
+ Install
59
+ ```bash
60
+ poetry install
61
+ ```
62
+
63
+ Usage
64
+ -----
65
+
66
+ ```python
67
+ >>> from pode import divide, Contour, Point, Polygon, Requirement
68
+ >>> contour = Contour([Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)])
69
+ >>> polygon = Polygon(contour)
70
+ >>> requirements = [Requirement(0.5), Requirement(0.5, point=Point(1, 1))]
71
+ >>> parts = divide(polygon, requirements)
72
+ >>> parts[0].area == parts[1].area < polygon.area
73
+ True
74
+ >>> Point(1, 1) in parts[1]
75
+ True
76
+
77
+ ```
78
+ Currently, the algorithm uses constrained Delaunay triangulation to form convex
79
+ parts which are used internally for a convex-polygon partition.
80
+ This triangulation, however, affects the resulting partition. The resulting
81
+ parts can have zigzag pattern separating different parts. In this way, the
82
+ solution can be far from being optimal in sense of the number of sides of the
83
+ resulting polygons. Alternatively, we implemented a helper function that would
84
+ join neighboring triangles if they form a larger convex part. It can be
85
+ imported as `from pode import joined_constrained_delaunay_triangles` and used
86
+ as `divide(polygon, requirements, joined_constrained_delaunay_triangles)`. But,
87
+ in the future, a better algorithm should be implemented, like
88
+ [Greene, D.H., 1983](https://www.goodreads.com/book/show/477772.Advances_in_Computing_Research_Volume_1)
89
+ or [Chazelle, B. and Dobkin, D., 1979](https://dl.acm.org/doi/abs/10.1145/800135.804396).
90
+
91
+ Development
92
+ -----------
93
+
94
+ ### Bumping version
95
+
96
+ #### Preparation
97
+
98
+ Install
99
+ [bump-my-version](https://github.com/callowayproject/bump-my-version/tree/master?tab=readme-ov-file#installation).
100
+
101
+ #### Pre-release
102
+
103
+ Choose which version number category to bump following [semver
104
+ specification](http://semver.org/).
105
+
106
+ Test bumping version
107
+ ```bash
108
+ bump-my-version bump --dry-run --verbose $CATEGORY
109
+ ```
110
+
111
+ where `$CATEGORY` is the target version number category name, possible
112
+ values are `patch`/`minor`/`major`.
113
+
114
+ Bump version
115
+ ```bash
116
+ bump-my-version bump --verbose $CATEGORY
117
+ ```
118
+
119
+ This will set version to `major.minor.patch-alpha`.
120
+
121
+ #### Release
122
+
123
+ Test bumping version
124
+ ```bash
125
+ bump-my-version bump --dry-run --verbose release
126
+ ```
127
+
128
+ Bump version
129
+ ```bash
130
+ bump-my-version bump --verbose release
131
+ ```
132
+
133
+ This will set version to `major.minor.patch`.
134
+
135
+ ### Publishing
136
+
137
+ Pushing a final release tag `vX.Y.Z` runs the CI publish jobs, which upload
138
+ the package to PyPI and push
139
+ the `prod` Docker image to the GitHub container registry (GHCR).
140
+ Pre-release tags such as `vX.Y.Z-alpha` are not published.
141
+
142
+ `bump-my-version bump release` commits and tags the release, so push both:
143
+ ```bash
144
+ git push --follow-tags
145
+ ```
146
+
147
+ One-time setup:
148
+
149
+ - GitHub: on PyPI, add a
150
+ [Trusted Publisher](https://docs.pypi.org/trusted-publishers/adding-a-publisher/)
151
+ for this repository with workflow `ci.yml` and environment `pypi`.
152
+ - GitHub: add a `CODECOV_TOKEN` repository secret from
153
+ [Codecov](https://codecov.io/).
154
+
155
+ ### Linting, formatting and type checking
156
+
157
+ [Ruff](https://docs.astral.sh/ruff/) is used for linting
158
+ (installed with the `dev` dependency group).
159
+
160
+ Check code
161
+ ```bash
162
+ ruff check .
163
+ ```
164
+
165
+ Fix automatically fixable issues
166
+ ```bash
167
+ ruff check --fix .
168
+ ```
169
+
170
+ [mypy](https://mypy.readthedocs.io/) checks types in strict mode
171
+ (configured in `pyproject.toml`)
172
+ ```bash
173
+ mypy .
174
+ ```
175
+
176
+ The package ships a `py.typed` marker, so projects that use it get its type
177
+ hints too.
178
+
179
+ To run these checks (Ruff and mypy) automatically on each commit,
180
+ install the [pre-commit](https://pre-commit.com/) hooks
181
+ (once, after the repository has been initialized with `git init`)
182
+ ```bash
183
+ pre-commit install
184
+ ```
185
+
186
+ ### Running tests
187
+
188
+ Install the project with the `dev` dependency group (pytest, pytest-cov,
189
+ Hypothesis)
190
+ ```bash
191
+ poetry install --with dev
192
+ ```
193
+
194
+ Run the tests
195
+ ```bash
196
+ poetry run pytest
197
+ ```
198
+
199
+ Run the tests with a coverage report, as CI does
200
+ ```bash
201
+ poetry run pytest --cov --cov-report=term
202
+ ```
203
+
204
+ Inside the dev container, dependencies are already installed into the
205
+ container's Python, so `poetry run` can be dropped: `pytest`.
206
+
207
+ Inside a `Docker` container (the default `IMAGE_TYPE=dev` image includes the
208
+ `dev` group)
209
+ ```bash
210
+ docker compose run --rm --entrypoint pytest pode
211
+ ```
212
+
213
+ ### Updating from the template
214
+
215
+ This project was generated from the
216
+ [copier-pypackage](https://github.com/GeorgySk/copier-pypackage) template.
217
+ To pull in a newer release of the template (CI, tooling and configuration
218
+ fixes), commit your changes, then run
219
+ ```bash
220
+ copier update --defaults
221
+ ```
222
+ Copier merges the template's changes into the project and keeps yours.
223
+ Review them with `git diff`, resolve any conflict markers and commit.
224
+ `CHANGES.rst` and `pode/__init__.py` are never touched by
225
+ updates, and `.copier-answers.yml` must not be edited by hand.
226
+
227
+ The `Template update` workflow (`.github/workflows/template-update.yml`) does
228
+ this every Monday and opens a pull request when there is a new template
229
+ release (run it by hand from the Actions tab). Conflicting changes are
230
+ committed with conflict markers in a draft pull request: resolve them on its
231
+ branch. There is one pull request per release, so closing one skips that
232
+ release. The template must be at a URL GitHub can clone (the `_src_path` in
233
+ `.copier-answers.yml`).
234
+
235
+ With the default `GITHUB_TOKEN`, enable "Allow GitHub Actions to create and
236
+ approve pull requests" (Settings → Actions → General). Even then the pull
237
+ request doesn't run CI, and updates that change `.github/workflows` can't be
238
+ pushed. To avoid both, add a `TEMPLATE_UPDATE_TOKEN` repository secret: a
239
+ fine-grained personal access token for this repository with read and write
240
+ access to Contents, Pull requests and Workflows.
@@ -0,0 +1,24 @@
1
+ """
2
+ Implementation the polygon decomposition algorithm by Hert, S. and
3
+ Lumelsky, V., 1998.
4
+ """
5
+
6
+ __author__ = "Georgy Skorobogatov"
7
+ __email__ = "skorobogatovgeorgy+github@gmail.com"
8
+ __version__ = "0.4.7"
9
+
10
+ from gon.base import (Contour,
11
+ Point,
12
+ Polygon)
13
+
14
+ from .pode import Requirement, divide
15
+ from .utils import joined_constrained_delaunay_triangles
16
+
17
+ __all__ = [
18
+ "Contour",
19
+ "Point",
20
+ "Polygon",
21
+ "Requirement",
22
+ "divide",
23
+ "joined_constrained_delaunay_triangles",
24
+ ]
@@ -0,0 +1,40 @@
1
+ """Type hints shared across the package."""
2
+
3
+ from collections.abc import Sequence
4
+ from fractions import Fraction
5
+ from typing import (Protocol,
6
+ TypeAlias)
7
+
8
+ from gon.base import (Contour,
9
+ Point,
10
+ Polygon,
11
+ Segment)
12
+ from ground.base import Context
13
+
14
+ #: Real number accepted as an area requirement. ``int`` is included
15
+ #: implicitly, as type checkers accept it wherever ``float`` is expected.
16
+ #: We don't use ``numbers.Real``, as type checkers don't support
17
+ #: arithmetic on it.
18
+ Scalar: TypeAlias = Fraction | float
19
+
20
+
21
+ class ConvexDivisorType(Protocol):
22
+ """Function that divides a polygon into convex parts."""
23
+
24
+ def __call__(self,
25
+ polygon: Polygon,
26
+ *,
27
+ extra_points: Sequence[Point] = (),
28
+ extra_constraints: Sequence[Segment] = (),
29
+ context: Context) -> list[Contour]:
30
+ """
31
+ Divides the polygon into convex parts.
32
+
33
+ :param polygon: polygon to divide
34
+ :param extra_points: points that must become vertices of the
35
+ parts
36
+ :param extra_constraints: segments that must lie on the borders
37
+ of the parts
38
+ :param context: geometric context
39
+ :return: borders of the convex parts
40
+ """