Is there an easy way to fill a 2d array after initialization? - c++

I currently have a 2d array in my program which stores the coordinates for a cube. It is initialized at the top and is easily filled with the values I want in it like so.
float cubeRef[3][8] = { { -1, 1, 1, -1, -1, 1, 1, -1 },
{ 1, 1, -1, -1, 1, 1, -1, -1 },
{ 1, 1, 1, 1, -1, -1, -1, -1, } };
However during my program the co ordinates change and I have a function which 'resets' them back to the default values you see above. However if I try to reset them using the same method as before.
cubeRef = { { -1, 1, 1, -1, -1, 1, 1, -1 },
{ 1, 1, -1, -1, 1, 1, -1, -1 },
{ 1, 1, 1, 1, -1, -1, -1, -1, } };
It will not work here, with error message "Expression must be a modifiable value".
Why can I not fill a 2d array after initializing the same way I can when I created it? And how can I return the 2d array to it's default values without having to fill each space individually?

You can't assign to an array, it's simply not possible.
You could have two arrays, the one you modify, and one which contains the default values. Then when you want to reset the modifiable array you just copy from the default array, either using std::copy, memcpy or in a loop.
Otherwise you have to manually set each entry, one by one.

Related

Arduino Icon Library

I'm working on an Arduino project and I want to display icons on a NeoMatrix 8x8 panel.
Initially, I went in direction that relied on inheritance, and requested some input on Arduino Stack Exchange where I was advised to go another route, and to ask my question elsewhere is it pertained more to C++ than to Arduino.
Instead of relying on inheritance, I was recommended to store my icons in PROGMEM and have the program build the icons from there.
I attempted the approach as much as I could, but I'm not at ease so I'd like some further insight!
The idea is to have a byte array that composes an 8x8 icon.
The values are 0-2, each representing a color set in an RGB struct array.
From what I believe I understand, my byte array stored in PROGMEM is read as a pointer, and needs to be accessed using ppm_read_byte.
I am unsure on how to handle the RGB struct. When I attempt to read it from PROGMEM, it causes my program to crash. So I removed it from PROGMEM, and the icon displays correctly. My byte array is in PROGMEM, but not the colors.
I am aware that I have a serious lack of knowledge about pointers which I need to work on...
Also, the idea is to have a collection of icons, so should I store all my icons (byte arrays and colors) in a header file? Will that not bloat it?
Thank you in advance for insight on this!
header.h
typedef struct {
byte r;
byte g;
byte b;
} RGB;
const byte PROGMEM WifiIcon[8][8] = {
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 2, 2, 2, 2, 1, 1},
{1, 2, 1, 1, 1, 1, 2, 1},
{2, 1, 2, 2, 2, 2, 1, 2},
{1, 2, 1, 1, 1, 1, 2, 1},
{1, 1, 1, 2, 2, 1, 1, 1},
{1, 1, 2, 1, 1, 2, 1, 1},
{0, 0, 0, 1, 1, 0, 0, 0}
};
const RGB WifiIconColors[3] = {
{0, 0, 0},
{0, 0, 0},
{0, 200, 61}
};
ESP8266Neomatrix.ino
#include "header.h"
void printIcon(int startPosition, const byte (&icon)[8][8], const RGB (&colors)[3]){
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
byte currentPixel = pgm_read_byte(&icon[i][j]);
const RGB currentColor = colors[currentPixel];
byte red = currentColor.r;
byte green = currentColor.g;
byte blue = currentColor.b;
matrix.setPixelColor(startPosition++, red, green, blue);
}
}
}
https://gist.github.com/Nate1661/0eea9200e9d1c86187c2acf205ba3602
If you want the RGB data to reside in PROGMEM, since it is not a native type handled by pgm_read_XXX functions, just read it with memcpy_P():
RGB currentColor;
memcpy_P(&currentColor, colors + currentPixel, sizeof(RGB));
If this crashes, then perhaps there is an issue with the value of currentPixel that you read.

TIFFSetField warning (unknown tag) when adding custom fields

I am creating a GeoTIFF and use the following code which seems to work fine, but the library generates a lot of warnings, specifically about the custom fields I am trying to add. Can anybody point out why this is the case or what I am doing wrong?
The warnings are specifically: TIFFSetField: [filename]: Unknown tag 34264 and TIFFSetField: [filename]: Unknown tag 34736
#define TIFFTAG_GEOTRANSMATRIX 34264
#define TIFFTAG_GEOKEYDIRECTORY 34735
#define TIFFTAG_GEODOUBLEPARAMS 34736
TIFF* tif = TIFFOpen(filename.c_str(), "w");
if (!tif) throw std::runtime_error("Error creating TIFF object");
// Add custom tags
// [enum, read count, write count, type, bit, ok to change, pass count, name]
// -1 for read count/write count signifies variable length
const TIFFFieldInfo xtiffFieldInfo[] = {
{ TIFFTAG_GEOTRANSMATRIX, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, 1, 1, (char*)"GeoTransformationMatrix" },
{ TIFFTAG_GEOKEYDIRECTORY, -1, -1, TIFF_SHORT, FIELD_CUSTOM, 1, 1, (char*)"GeoKeyDirectory" },
{ TIFFTAG_GEODOUBLEPARAMS, -1, -1, TIFF_DOUBLE, FIELD_CUSTOM, 1, 1, (char*)"GeoDoubleParams" },
};
TIFFMergeFieldInfo(tif, xtiffFieldInfo, 3); // manually set 3 for testing
TIFFSetField(tif, TIFFTAG_GEOTRANSMATRIX, 16, &xform[0]); // <- generates warning
{
const Float64 tmp[2] = { 298.257223563, // GeogInvFlatteningGeoKey
6378137.0 }; // GeogSemiMajorAxisGeoKey; WGS 84 reference ellipsoid defines 6,378,137m
TIFFSetField(tif, TIFFTAG_GEODOUBLEPARAMS, 2, &tmp[0]); // <- generates warning
}
// Write a few other tags and image scanlines
TIFFClose(tif);

OpenCV: Accessing values of a matrix

I am using the OpenCV function decomposeHomographyMat(). Because I want to decompose my H1 and H2 matrices I have got from the OpenCV function stereoRectifyUncalibrated().
Just for testing I wanted to multiply the rotation and translation back together to see if the result are the same and everything works correct.
decomposeHomographyMat(H1, Mat(Identity), result_rot, result_trans, result_normals);
Matx44f rotM(result_rot[id].at<float>(0,0), result_rot[id].at<float>(0,0), result_rot[id].at<float>(0,0), 0,
result_rot[id].at<float>(0,0), result_rot[id].at<float>(0,0), result_rot[id].at<float>(0,0), 0,
result_rot[id].at<float>(0,0), result_rot[id].at<float>(0,0), result_rot[id].at<float>(0,0), 0,
0, 0, 0, 1);
Matx44f transM(1, 0, 0, result_trans[id].at<float>(0,0),
0, 1, 0, result_trans[id].at<float>(0,1),
0, 0, 1, result_trans[id].at<float>(0,2),
0, 0, 0, 1);
H1 = Mat(transM) * Mat(rotM);
I know that for the rotM matrix I am referencing the same value all the time, this is jut temporary.
My problem is, that if I print out result_rot[id] and rotM I get weir result:
result_rot[id]: [0.9920521909211247, -0.1258265282306712, 0.0003678069998755973;
0.1258266147675855, 0.9920522232074044, -0.0002223635722913286;
-0.0003369043855492455, 0.0002668761040765017, 0.9999999076363849]
rotM: [-0.015474273, -0.015474273, -0.015474273, 0;
-0.015474273, -0.015474273, -0.015474273, 0;
-0.015474273, -0.015474273, -0.015474273, 0;
0, 0, 0, -0.99892187]
The value -0.015474273 is not even in the original rotationmatrix and the value 1 seems to be stored as -0.99892187.
I also tried to replace float with double, then the result changes again but still not correct.
How can I properly get the correct value that was stored in that matrix? and what is going wrong here?

Should each element of a 2d array create a new Sprite object?

I'm trying to create a tilemap with a 2d array and was struggling slightly with it. When I iterate through the array should I create a new Sprite object for each element in the array or is it possible to just create a sprite object for each of the different tiles then copy them to the relevant positions on screen. For example - note Rows and Columns are const ints already initialised to 5
int MazeMap[Rows][Columns] = { //Should the array type be int or Sprite*
{1, 1, 1, 1, 1},
{1, 0, 0, 0, 1},
{1, 0, 1, 1, 1},
{1, 0, 0, 0, 1},
{1, 1, 1, 1, 1}
};
for(int x = 0; x<Rows; x++)
{
for(int y = 0; y<Columns; y++)
{
if(MazeMap[x][y]==1)
{
//should I create a new Sprite object here or should I create
// a Tile1 sprite object above the array and then just pass it into
//this array to draw it to the screen?
}
}
}
To me it just seems really inefficient to have (in this case) 25 sprite objects when you can just have 2 sprite objects and copy them to a number of different locations on screen.

Unit-testing code with a large number of interdependent conditions

I'm testing a set of output styler classes which style data before outputting it to an output interface. The behavior of each styler is dependent on up to 5 different conditions (at the moment, but a sixth is on the way) with regard to the object being outputted: isKey, isDefault, isEmpty, isReadOnly, isAccessible
So one styler might output nothing if it has readonly data, while another might show "access denied".
At the moment I am testing along these lines, but the tests are exploding as more conditions are added.
{
// isKey, isDefault, isEmpty, isReadOnly, isAccessible
ValueOutputTester::TestConditions conditions = {0, 0, 0, 0, 0};
EXPECT_EQ(valueOutputTester(conditions), accessDeniedOutput);
}
{
ValueOutputTester::TestConditions conditions = {0, 0, 0, 0, 1};
EXPECT_EQ(valueOutputTester(conditions), normalOutput);
}
{
ValueOutputTester::TestConditions conditions = {0, 0, 0, 1, 0};
EXPECT_EQ(valueOutputTester(conditions), accessDeniedOutput);
}
{
ValueOutputTester::TestConditions conditions = {0, 0, 0, 1, 1};
EXPECT_EQ(valueOutputTester(conditions), accessDeniedOutput);
}
{
ValueOutputTester::TestConditions conditions = {0, 0, 1, 0, 0};
EXPECT_EQ(valueOutputTester(conditions), emptyOutput);
}
...
Can you recommend a better way of doing this?
You might write a test helper method that lets you specify condition patterns and that generates all combinations that match the pattern, e.g. assuming -1 means 'either 0 or 1':
TestPattern pattern = {-1, -1, 1, -1, -1};
ExpectForPattern(pattern, emptyOutput);