3template<size_t pixelCount>
4PixelGroup<pixelCount>::PixelGroup(Vector2D size, Vector2D position, uint16_t rowCount){
6 this->position = position;
7 this->rowCount = rowCount;
8 this->colCount = pixelCount / rowCount;
12 bounds.UpdateBounds(position);
13 bounds.UpdateBounds(position + size);
15 for(uint16_t i = 0; i < pixelCount; i++){
16 pixelColors[i] = RGBColor();
17 pixelBuffer[i] = RGBColor();
28template<size_t pixelCount>
29PixelGroup<pixelCount>::PixelGroup(const Vector2D* pixelLocations, Direction direction){
30 this->direction = direction;
31 pixelPositions = pixelLocations;
33 for(uint16_t i = 0; i < pixelCount; i++){
34 pixelColors[i] = RGBColor();
35 pixelBuffer[i] = RGBColor();
37 bounds.UpdateBounds(pixelLocations[i]);
48template<size_t pixelCount>
49PixelGroup<pixelCount>::~PixelGroup(){}
51template<size_t pixelCount>
52Vector2D PixelGroup<pixelCount>::GetCenterCoordinate(){
53 return (bounds.GetMaximum() + bounds.GetMinimum()) / 2.0f;
56template<size_t pixelCount>
57Vector2D PixelGroup<pixelCount>::GetSize(){
58 return bounds.GetMaximum() - bounds.GetMinimum();
61template<size_t pixelCount>
62Vector2D PixelGroup<pixelCount>::GetCoordinate(uint16_t count){
63 count = Mathematics::Constrain<int>(count, 0, pixelCount);
66 float row = count % rowCount;
67 float col = (count - row) / rowCount;
69 tempLocation.X = Mathematics::Map(row, 0.0f, float(rowCount), position.X, position.X + size.X);
70 tempLocation.Y = Mathematics::Map(col, 0.0f, float(colCount), position.Y, position.Y + size.Y);
75 if(direction == ZEROTOMAX){
76 return pixelPositions[count];
79 return pixelPositions[pixelCount - count - 1];
84template<size_t pixelCount>
85int PixelGroup<pixelCount>::GetPixelIndex(Vector2D location){
86 float row = Mathematics::Map(location.X, position.X, position.X + size.X, 0.0f, float(rowCount));
87 float col = Mathematics::Map(location.Y, position.Y, position.Y + size.Y, 0.0f, float(colCount));
89 uint16_t count = row + col * rowCount;
91 if (count < pixelCount && count > 0 && row > 0 && row < rowCount && col > 0 && col < colCount){
99template<size_t pixelCount>
100RGBColor* PixelGroup<pixelCount>::GetColor(uint16_t count){
101 return &pixelColors[count];
104template<size_t pixelCount>
105RGBColor* PixelGroup<pixelCount>::GetColors(){
106 return &pixelColors[0];
109template<size_t pixelCount>
110RGBColor* PixelGroup<pixelCount>::GetColorBuffer(){
111 return &pixelBuffer[0];
114template<size_t pixelCount>
115uint16_t PixelGroup<pixelCount>::GetPixelCount(){
119template<size_t pixelCount>
120bool PixelGroup<pixelCount>::Overlaps(BoundingBox2D* box){
121 return bounds.Overlaps(box);
124template<size_t pixelCount>
125bool PixelGroup<pixelCount>::ContainsVector2D(Vector2D v){
126 return v.CheckBounds(bounds.GetMinimum(), bounds.GetMaximum());
129template<size_t pixelCount>
130bool PixelGroup<pixelCount>::GetUpIndex(uint16_t count, uint16_t* upIndex){
131 *upIndex = up[count];
133 return up[count] < 65535;
136template<size_t pixelCount>
137bool PixelGroup<pixelCount>::GetDownIndex(uint16_t count, uint16_t* downIndex){
138 *downIndex = down[count];
140 return down[count] < 65535;
143template<size_t pixelCount>
144bool PixelGroup<pixelCount>::GetLeftIndex(uint16_t count, uint16_t* leftIndex){
145 *leftIndex = left[count];
147 return left[count] < 65535;
150template<size_t pixelCount>
151bool PixelGroup<pixelCount>::GetRightIndex(uint16_t count, uint16_t* rightIndex){
152 *rightIndex = right[count];
154 return right[count] < 65535;
157template<size_t pixelCount>
158bool PixelGroup<pixelCount>::GetAlternateXIndex(uint16_t count, uint16_t* index){
159 uint16_t tempIndex = count;
160 bool isEven = count % 2;
163 for(uint16_t i = 0; i < count / 2; i++){
165 valid = GetRightIndex(tempIndex, &tempIndex);
168 valid = GetLeftIndex(tempIndex, &tempIndex);
179template<size_t pixelCount>
180bool PixelGroup<pixelCount>::GetAlternateYIndex(uint16_t count, uint16_t* index){
181 uint16_t tempIndex = count;
182 bool isEven = count % 2;
185 for(uint16_t i = 0; i < count / 2; i++){
187 valid = GetUpIndex(tempIndex, &tempIndex);
190 valid = GetDownIndex(tempIndex, &tempIndex);
201template<size_t pixelCount>
202bool PixelGroup<pixelCount>::GetOffsetXIndex(uint16_t count, uint16_t* index, int x1){
203 uint16_t tempIndex = count;
206 for(int i = 0; i < x1; i++){
207 if (x1 > 0) valid = GetRightIndex(tempIndex, &tempIndex);
208 else if (x1 < 0) valid = GetLeftIndex(tempIndex, &tempIndex);
219template<size_t pixelCount>
220bool PixelGroup<pixelCount>::GetOffsetYIndex(uint16_t count, uint16_t* index, int y1){
221 uint16_t tempIndex = count;
224 for(int i = 0; i < y1; i++){
225 if (y1 > 0) valid = GetUpIndex(tempIndex, &tempIndex);
226 else if (y1 < 0) valid = GetDownIndex(tempIndex, &tempIndex);
237template<size_t pixelCount>
238bool PixelGroup<pixelCount>::GetOffsetXYIndex(uint16_t count, uint16_t* index, int x1, int y1){
239 uint16_t tempIndex = count;
242 for(int i = 0; i < abs(x1); i++){
243 if (x1 > 0) valid = GetRightIndex(tempIndex, &tempIndex);
244 else if (x1 < 0) valid = GetLeftIndex(tempIndex, &tempIndex);
250 for(int i = 0; i < abs(y1); i++){
251 if (y1 > 0) valid = GetUpIndex(tempIndex, &tempIndex);
252 else if (y1 < 0) valid = GetDownIndex(tempIndex, &tempIndex);
263template<size_t pixelCount>
264bool PixelGroup<pixelCount>::GetRadialIndex(uint16_t count, uint16_t* index, int pixels, float angle){//walks in the direction of the angle to a target pixel to grab an index
265 int x1 = int(float(pixels) * cosf(angle * Mathematics::MPID180));
266 int y1 = int(float(pixels) * sinf(angle * Mathematics::MPID180));
268 uint16_t tempIndex = count;
277 for(int i = 0; i < pixels; i++){
278 x = Mathematics::Map(i, 0, pixels, 0, x1);
279 y = Mathematics::Map(i, 0, pixels, 0, y1);
281 for (int k = 0; k < abs(x - previousX); k++){
282 if (x > previousX) valid = GetRightIndex(tempIndex, &tempIndex);
283 else if (x < previousX) valid = GetLeftIndex(tempIndex, &tempIndex);
289 for (int k = 0; k < abs(y - previousY); k++){
290 if (y > previousY) valid = GetUpIndex(tempIndex, &tempIndex);
291 else if (y < previousY) valid = GetDownIndex(tempIndex, &tempIndex);
306template<size_t pixelCount>
307void PixelGroup<pixelCount>::GridSort(){
309 // Loop through all pixels
310 for (uint16_t i = 0; i < pixelCount; i++) {
313 if(!isRectangular) currentPos = direction == ZEROTOMAX ? pixelPositions[i] : pixelPositions[pixelCount - i - 1];
314 else currentPos = direction == ZEROTOMAX ? GetCoordinate(i) : GetCoordinate(pixelCount - i - 1);
316 // Initialize the minimum distances and indices to the first pixel
317 float minUp = Mathematics::FLTMAX, minDown = Mathematics::FLTMAX, minLeft = Mathematics::FLTMAX, minRight = Mathematics::FLTMAX;
318 int minUpIndex = -1, minDownIndex = -1, minLeftIndex = -1, minRightIndex = -1;
320 // Loop through all other pixels
321 for (uint16_t j = 0; j < pixelCount; j++) {
322 if (i == j) { continue; } // Skip the current pixel
324 Vector2D neighborPos;
326 if(!isRectangular) neighborPos = direction == ZEROTOMAX ? pixelPositions[j] : pixelPositions[pixelCount - j - 1];
327 else currentPos = direction == ZEROTOMAX ? GetCoordinate(j) : GetCoordinate(pixelCount - j - 1);
329 // Calculate the distances between the current pixel and the other pixel
330 float dist = currentPos.CalculateEuclideanDistance(neighborPos);
332 // Check if the other pixel is above or below the current pixel
333 if (Mathematics::IsClose(currentPos.X, neighborPos.X, 1.0f)) {
334 if (currentPos.Y < neighborPos.Y && dist < minUp) {
338 else if (currentPos.Y > neighborPos.Y && dist < minDown) {
344 // Check if the other pixel is to the left or right of the current pixel
345 if (Mathematics::IsClose(currentPos.Y, neighborPos.Y, 1.0f)) {
346 if (currentPos.X > neighborPos.X && dist < minLeft) {
350 else if (currentPos.X < neighborPos.X && dist < minRight) {
357 // Set the indices of the neighboring pixels
358 if (minUpIndex != -1) up[i] = minUpIndex;
359 if (minDownIndex != -1) down[i] = minDownIndex;
361 if (minLeftIndex != -1) left[i] = minLeftIndex;
362 if (minRightIndex != -1) right[i] = minRightIndex;
365 else {//optimized algorithm for rectangular matrices
366 for (int i = 0; i < int(pixelCount); i++) {
367 if (i + int(rowCount) < int(pixelCount) - 1) up[i] = uint16_t(i) + rowCount;//up
368 if (i - int(rowCount) > 1) down[i] = uint16_t(i) - rowCount;//down
370 if (!(i % rowCount == 0) && i > 1) left[i] = uint16_t(i) - 1;//left
371 if (!(i % rowCount + 1 == 0) && i < int(pixelCount) - 1) right[i] = uint16_t(i) + 1;//right