Porytiles
Loading...
Searching...
No Matches
canonical_pixel_tile.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <array>
5#include <vector>
6
9
10namespace porytiles {
11
35template <SupportsTransparency PixelType>
36class CanonicalPixelTile : public PixelTile<PixelType> {
37 public:
55 explicit CanonicalPixelTile(const PixelTile<PixelType> &tile) : PixelTile<PixelType>{}
56 {
57 // Helper struct to store candidate tiles with their flip flags
58 struct Candidate {
59 PixelTile<PixelType> flipped_tile;
60 bool h_flip;
61 bool v_flip;
62
63 auto operator<=>(const Candidate &other) const
64 {
65 return flipped_tile <=> other.flipped_tile;
66 }
67 };
68
69 std::array flips = {
70 std::pair{false, false}, std::pair{false, true}, std::pair{true, false}, std::pair{true, true}};
71
72 std::vector<Candidate> candidates;
73 candidates.reserve(4);
74
75 for (const auto &[h, v] : flips) {
76 candidates.push_back({tile.flip(h, v), h, v});
77 }
78
79 auto min_candidate = *std::min_element(candidates.begin(), candidates.end());
80
81 // Assign the canonical tile data
82 *static_cast<PixelTile<PixelType> *>(this) = min_candidate.flipped_tile;
83 h_flip_ = min_candidate.h_flip;
84 v_flip_ = min_candidate.v_flip;
85 }
86
104 CanonicalPixelTile(const PixelTile<PixelType> &tile, const PixelType &extrinsic_transparency)
105 requires requires(const PixelType &p) { p.is_transparent(p); }
107 {
108 struct Candidate {
109 PixelTile<PixelType> flipped_tile;
110 bool h_flip;
111 bool v_flip;
112 };
113
114 std::array flips = {
115 std::pair{false, false}, std::pair{false, true}, std::pair{true, false}, std::pair{true, true}};
116
117 std::vector<Candidate> candidates;
118 candidates.reserve(4);
119 for (const auto &[h, v] : flips) {
120 candidates.push_back({tile.flip(h, v), h, v});
121 }
122
123 auto min_it = std::min_element(
124 candidates.begin(), candidates.end(), [&extrinsic_transparency](const Candidate &a, const Candidate &b) {
125 return PixelTile<PixelType>::cross_et_compare(
126 a.flipped_tile, extrinsic_transparency, b.flipped_tile, extrinsic_transparency) < 0;
127 });
128
129 *static_cast<PixelTile<PixelType> *>(this) = min_it->flipped_tile;
130 h_flip_ = min_it->h_flip;
131 v_flip_ = min_it->v_flip;
132 }
133
145 auto operator<=>(const CanonicalPixelTile &other) const = default;
146
154 [[nodiscard]] bool h_flip() const
155 {
156 return h_flip_;
157 }
158
166 [[nodiscard]] bool v_flip() const
167 {
168 return v_flip_;
169 }
170
171 private:
172 bool h_flip_;
173 bool v_flip_;
174};
175
176} // namespace porytiles
A PixelTile representation that stores the canonical (lexicographically minimal) orientation among al...
bool h_flip() const
Returns the horizontal flip flag.
bool v_flip() const
Returns the vertical flip flag.
CanonicalPixelTile(const PixelTile< PixelType > &tile, const PixelType &extrinsic_transparency)
Canonicalizes the input tile's orientation under cross-ET strict weak ordering.
CanonicalPixelTile(const PixelTile< PixelType > &tile)
Constructs a CanonicalPixelTile by finding the canonical orientation of the input tile.
auto operator<=>(const CanonicalPixelTile &other) const =default
Three-way comparison operator that compares all fields in lexicographic order.
An 8x8 tile backed by literal-array-based per-pixel storage of an arbitrary pixel type.