Project the given geometries to 2D. :param kind: The type of projection to use. Can be one of 'I', 'pca', 'svd', 'isometric', 'auto', 'xy', 'xz', or 'yz'. :param dimensions: The target dimensionality of the projection for PCA, SVD, or isometric. :param scale: A multiplicative scale fact
(
tagged_points: TaggedPointSequence, kind="pca", dimensions=2, scale=1.0
)
| 11 | |
| 12 | |
| 13 | def project( |
| 14 | tagged_points: TaggedPointSequence, kind="pca", dimensions=2, scale=1.0 |
| 15 | ) -> TaggedPointSequence: |
| 16 | """Project the given geometries to 2D. |
| 17 | |
| 18 | :param kind: The type of projection to use. Can be one of 'I', 'pca', 'svd', 'isometric', 'auto', 'xy', 'xz', or 'yz'. |
| 19 | :param dimensions: The target dimensionality of the projection for PCA, SVD, or isometric. |
| 20 | :param scale: A multiplicative scale factor. |
| 21 | """ |
| 22 | if kind in ("xy", "xz", "yz"): |
| 23 | transformed_point_sequence = _drop_coord(tagged_points, kind, scale) |
| 24 | elif kind in ("pca", "svd"): |
| 25 | transformed_point_sequence = _fit_transform(tagged_points, kind, dimensions, scale) |
| 26 | elif kind == "isometric": |
| 27 | transformed_point_sequence = _isometric(tagged_points, dimensions, scale) |
| 28 | elif kind == "auto": |
| 29 | # PCA has tended to flip things upside down, to flip about the x axis by 180 and rotate a |
| 30 | # a bit to ensure no symmetry |
| 31 | decomp = PCA(n_components=3) |
| 32 | points, tags = unzip(tagged_points) |
| 33 | points = scale * np.array(list(_zeropad_3d(points))) |
| 34 | transformed = decomp.fit_transform(points) |
| 35 | logger.error(transformed.shape) |
| 36 | rotation = _rot_x(radians(180)) @ _rot_z(radians(13)) |
| 37 | transformed = transformed @ rotation |
| 38 | return zip(transformed[:, :dimensions], tags) |
| 39 | elif kind == "I": |
| 40 | points, tags = unzip(tagged_points) |
| 41 | if scale != 1.0: |
| 42 | points = (tuple(scale * c for c in point) for point in points) |
| 43 | transformed_point_sequence = zip(points, tags) |
| 44 | else: |
| 45 | raise ValueError(f"Unsupported projection type '{kind=}'") |
| 46 | |
| 47 | return transformed_point_sequence |
| 48 | |
| 49 | |
| 50 | def unzip(iterable): |
no test coverage detected