From 23c094bb71eb415aa49dbc15d51fd46832746222 Mon Sep 17 00:00:00 2001 From: Pavel Naboka <35613006+Zanzibarra@users.noreply.github.com> Date: Tue, 5 Sep 2023 15:54:19 +0300 Subject: [PATCH] =?UTF-8?q?dev:=20=D0=9F=D0=B5=D1=80=D0=B2=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=B8=D1=82=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Пока только простое преобразование и отрисовка графика. Без передачи информации о преобразованиях --- .gitignore | 1 + main.py | 34 ++++++++++++++++++++++++++++++++++ pyproject.toml | 16 ++++++++++++++++ transformations.py | 17 +++++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 .gitignore create mode 100644 main.py create mode 100644 pyproject.toml create mode 100644 transformations.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c04bc49 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +poetry.lock diff --git a/main.py b/main.py new file mode 100644 index 0000000..51253f2 --- /dev/null +++ b/main.py @@ -0,0 +1,34 @@ +from pathlib import Path + +import numpy +from matplotlib import pyplot + +from transformations import centroid, kabsch_algorithm + +expected_points_file_path = Path('expected_points.txt') +actual_points_file_path = Path('actual_points.txt') + +plot_3d = pyplot.figure().add_subplot(projection='3d') + + +def read_points_from_file(points_file_path: Path) -> numpy.ndarray: + with points_file_path.open('r') as points_file: + return numpy.array([[float(coordinate) for coordinate in point_line.strip().split(' ')] + for point_line in points_file]) + + +if __name__ == '__main__': + expected_points = read_points_from_file(expected_points_file_path) + actual_points = read_points_from_file(actual_points_file_path) + + expected_points -= centroid(expected_points) + actual_points -= centroid(actual_points) + + actual_points = numpy.dot(actual_points, kabsch_algorithm(actual_points, expected_points)) + + plot_3d.plot(actual_points[:, 0], actual_points[:, 1], actual_points[:, 2], 'o-', markersize=12, linewidth=3) + plot_3d.plot(expected_points[:, 0], expected_points[:, 1], expected_points[:, 2], 'o-', markersize=12, linewidth=3) + plot_3d.grid(True) + plot_3d.tick_params(labelsize=15) + + pyplot.show() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..4c16523 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,16 @@ +[tool.poetry] +name = "reinmetal" +version = "0.1.0" +description = "" +authors = ["Pavel Naboka "] + +[tool.poetry.dependencies] +python = "^3.10" +numpy = "^1.25.2" + +[tool.poetry.dev-dependencies] +matplotlib = "^3.7.2" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/transformations.py b/transformations.py new file mode 100644 index 0000000..0dec312 --- /dev/null +++ b/transformations.py @@ -0,0 +1,17 @@ +import numpy + + +def centroid(points: numpy.ndarray) -> numpy.ndarray: + return points.mean(axis=0) + + +def kabsch_algorithm(actual_points: numpy.ndarray, expected_points: numpy.ndarray) -> numpy.ndarray: + # TODO Заменить безликие C, V, S, W на что-то более внятное + C = numpy.dot(numpy.transpose(actual_points), expected_points) + V, S, W = numpy.linalg.svd(C) + + if (numpy.linalg.det(V) * numpy.linalg.det(W)) < 0.0: + S[-1] = -S[-1] + V[:, -1] = -V[:, -1] + + return numpy.dot(V, W)