I'm trying to make use of precalculated values by outputting them to a header file and then compiling them for use.
The precalculated values are cube co ordinates mapped onto a sphere and the data structure takes the form of:
typedef float heightMapCubeFace[5][5][3];
I am defining each face seperately like so:
heightMapCubeFace face1 = {{{ -2.88675, -2.88675, -2.88675 }, { -3.38502, -3.38502, -1.44338 }, { -3.53553, -3.53553, 0 }, { -3.38502, -3.38502, 1.44338 }, { -2.88675, -2.88675, 2.88675}},
{{ -1.44338, -3.38502, -3.38502 }, { -1.69251, -4.38986, -1.69251 }, { -1.76777, -4.67707, 0 }, { -1.69251, -4.38986, 1.69251 }, { -1.44338, -3.38502, 3.38502}},
{{ 0, -3.53553, -3.53553 }, { 0, -4.67707, -1.76777 }, { 0, -5, 0 }, { 0, -4.67707, 1.76777 }, { 0, -3.53553, 3.53553}},
{{ 1.44338, -3.38502, -3.38502 }, { 1.69251, -4.38986, -1.69251 }, { 1.76777, -4.67707, 0 }, { 1.69251, -4.38986, 1.69251 }, { 1.44338, -3.38502, 3.38502}},
{{ 2.88675, -2.88675, -2.88675 }, { 3.38502, -3.38502, -1.44338 }, { 3.53553, -3.53553, 0 }, { 3.38502, -3.38502, 1.44338 }, { 2.88675, -2.88675, 2.88675}}
};
and finally:
heightMapCubeFace * heightMapSaved[6] = {&face1, &face2, &face3, &face4, &face5, &face6};
Eventually the data structue will be bigger I hav ejust set it to 5x5 to make things easier at first.
The problem I am having is when I want to get the values back, something weird is happening and as a result access violations are occuring.
As shown in the following image
As you can see the assigned value does not match that of the data structure. Instead the value for index [0][0][0][1] is given the value of index [0][0][1][0].
here
I picked up on this because an unhaddled exception is thrown at a later stage (access violation), I think it is because of this index problem but can't be certain.
I don't understand what is going on, am I dereferencing the pointer wrong?
Any help would be much appriciated, thanks.
Here is the code for that section:
for(int i = 0; i < 6; i++)
{
for(int j = 0; j < heightMapRes; j++)
{
for(int k = 0; k < heightMapRes; k++)
{
float xCoord = *(heightMapSaved[i][j][k][0]);
float yCoord = *(heightMapSaved[i][j][k][1]);
float zCoord = *(heightMapSaved[i][j][k][2]);
float newValue = myModule.GetValue( xCoord, yCoord, zCoord);
heightMap.SetValue( j, k, newValue);
}
}
}
layout is (heightMapSaved[6])[5][5][3] not (heightMapSaved[5][5][3][6])
Related
In JavaScript I might iterate over a set of objects containing data, like this:
const components = [
{
id: 1,
pin: "A0",
name: "light"
},
{
id: 2,
pin: "A1",
name: "sound"
},
{
id: 1,
pin: "A0",
name: "heat"
},
]
for (const component of components) {
const value = analogRead(component.pin);
console.log(`${component.name}:value`)
}
I often have a need to use code like this on the Arduino, but I'm not sure how I'd go about it.
NOTE: I'm not looking for an exact translation of this into C++; I want to know what the standard pattern is for achieving this is when using Arduino.
You can use C structure. To do so you need to declare a structure first describing your object type.
struct component
{
int id;
char pin[10];
char name[50];
};
component components[] = {
{
1,
"A0",
"light"},
{
2,
"A1",
"sound"},
{
1,
"A0",
"heat"}
};
int main ()
{
int len = sizeof(components)/sizeof(components[0]);
for (int i=0 ; i<len ; i++)
{
printf("{ id: %d , pin: \"%s\" , name: \"%s\" }\n",components[i].id, components[i].pin, components[i].name);
}
return 0;
}
Output:
{ id: 1 , pin: "A0" , name: "light" }
{ id: 2 , pin: "A1" , name: "sound" }
{ id: 1 , pin: "A0" , name: "heat" }
If you're using modern C++ (11 or newer, which I understand arduino support), and your data is stored in an array you can simply do the following:
int values[5] = { 16, 2, 77, 40, 12071 }
for(auto const& value: values) {
// Do stuff
}
I am trying to create a function that counts the people of each category that have a value bigger than 0. If this is my data...
DATA.CSV
name; category; value
name1; A; 10
name2; A; 0
name3; A; 5
name4; B; 7
name5; B; 3
name6; C; 0
...I should get the following results
count(dataset, "A")=2
count(dataset, "B")=2
count(dataset, "C")=0
EDIT! I am actually loading data from a .json file
[
{
"voce":"amministrazione",
"categoria":"funzioni",
"val2015":404571081
},
{
"voce":"sociale",
"categoria":"funzioni",
"val2015":235251679
},
{
"voce":"territorio e ambiente",
"categoria":"funzioni",
"val2015":286164667
},
{
"voce":"viabilità e trasporti ",
"categoria":"funzioni",
"val2015":144185664
},
{
"voce":"istruzione",
"categoria":"funzioni",
"val2015":168774925
},
{
"voce":"cultura ",
"categoria":"funzioni",
"val2015":55868045
},
{
"voce":"sport",
"categoria":"funzioni",
"val2015":27219432
},
{
"voce":"turismo",
"categoria":"funzioni",
"val2015":9544845
},
{
"voce":"sviluppo economico",
"categoria":"funzioni",
"val2015":14790363
},
{
"voce":"servizi produttivi",
"categoria":"funzioni",
"val2015":4334
},
{
"voce":"polizia locale",
"categoria":"funzioni",
"val2015":99007202
},
{
"voce":"giustizia ",
"categoria":"funzioni",
"val2015":12147068
},
{
"voce":"anticipazioni di cassa",
"categoria":"rimborso prestiti",
"val2015":304323808
},
{
"voce":"finanziamenti a breve termine",
"categoria":"rimborso prestiti",
"val2015":0
},
{
"voce":"prestiti obbligazionari",
"categoria":"rimborso prestiti",
"val2015":38842996
},
{
"voce":"quota capitale di debiti pluriennali",
"categoria":"rimborso prestiti",
"val2015":0
},
{
"voce":"quota capitale di mutui e prestiti",
"categoria":"rimborso prestiti",
"val2015":128508755
},
{
"voce":"spese per conto terzi",
"categoria":"",
"val2015":232661261
},
{
"voce":"disavanzo di amministrazione",
"categoria":"",
"val2015":0
}
]
I tried a for loop with an if statement inside but it is not working.
function count (dataset, chosenCategory) {
var count = 0;
for (d in dataset) {
if (d.categoria==chosenCategory && d.val2015>0) {
count += 1;
} else {
count += 0;
}
}
}
What am I doing wrong?
have you tried changing "d.value" to "+d.value"?
If they're from a csv file, values are generally loaded as strings, so everything you want to treat as a number needs converted to a number, and the '+' does that.
try it in your console
"1">0
false
+"1">0
true
PS. You don't need the else condition
Due to the need to be able to reference unicode character groups in a header only implementation, I want to declare all the arrays first. Templates allow me to initialize static members in the header, but the code looks messy.
This is just two of the twenty or so groups:
struct CharacterClass
{
struct Value
{
int l;
int h;
};
};
template < int N >
struct Nd : public CharacterClass
{
static const Value v[];
};
template< int N >
const typename Nd< N >::Value Nd< N >::v[] = {
{ 0x00030 , 0x00039 }, { 0x00660 , 0x00669 }, { 0x006f0 , 0x006f9 }, { 0x007c0 , 0x007c9 }, { 0x00966 , 0x0096f },
{ 0x009e6 , 0x009ef }, { 0x00a66 , 0x00a6f }, { 0x00ae6 , 0x00aef }, { 0x00b66 , 0x00b6f }, { 0x00be6 , 0x00bef },
{ 0x00c66 , 0x00c6f }, { 0x00ce6 , 0x00cef }, { 0x00d66 , 0x00d6f }, { 0x00e50 , 0x00e59 }, { 0x00ed0 , 0x00ed9 },
{ 0x00f20 , 0x00f29 }, { 0x01040 , 0x01049 }, { 0x017e0 , 0x017e9 }, { 0x01810 , 0x01819 }, { 0x01946 , 0x0194f },
{ 0x019d0 , 0x019d9 }, { 0x01b50 , 0x01b59 }, { 0x0ff10 , 0x0ff19 }
};
template < int N >
struct Nl : public CharacterClass
{
static const Value v[];
};
template< int N >
const typename Nl< N >::Value Nl< N >::v[] = {
{ 0x016ee , 0x016f0 }, { 0x02160 , 0x02182 }, { 0x03007, 0x03007 }, { 0x03021 , 0x03029}, { 0x03038 , 0x0303a }
};
Q1: Is it possible to declare the array once in a base class without having to repeat it for each derived type?
Q2: How can I hide the dummy 'int N', so that I can later reference the structs without having to add the template parameter? ie. int x = Nd.v[10].l;
Q3: Is there a better way of doing this?
I will try to give you an alternative for Q1 you've asked.
I don't like to see hard-coded values which are meaningless to the program logics.
Here's a nice trick That I use sometimes:
Create a new file and paste the values in it.
data.dat
{ 0x00030 , 0x00039 }, { 0x00660 , 0x00669 }, { 0x006f0 , 0x006f9 }, { 0x007c0 , 0x007c9 }, { 0x00966 , 0x0096f },
{ 0x009e6 , 0x009ef }, { 0x00a66 , 0x00a6f }, { 0x00ae6 , 0x00aef }, { 0x00b66 , 0x00b6f }, { 0x00be6 , 0x00bef },
{ 0x00c66 , 0x00c6f }, { 0x00ce6 , 0x00cef }, { 0x00d66 , 0x00d6f }, { 0x00e50 , 0x00e59 }, { 0x00ed0 , 0x00ed9 },
{ 0x00f20 , 0x00f29 }, { 0x01040 , 0x01049 }, { 0x017e0 , 0x017e9 }, { 0x01810 , 0x01819 }, { 0x01946 , 0x0194f },
{ 0x019d0 , 0x019d9 }, { 0x01b50 , 0x01b59 }, { 0x0ff10 , 0x0ff19 }
now, when you want to repeat it, do the following:
const typename Nd< N >::Value Nd< N >::v[] = {
#include "data.dat"
};
This way, the preprocessor will paste all this values for you, so you don't need to repeat them all the time.
Answering my own questions. I placed the whole combined array in a base class, then derived from that with derived types initializing themselves to an index within the array.
struct CharacterClass
{
struct Value
{
int l;
int h;
};
};
template < int X >
struct Base : public CharacterClass
{
static const Value v[];
};
template< int X >
const typename Base< X >::Value Base< X >::v[] = {
// Nd values length 23 index 0
{ 0x00030 , 0x00039 }, { 0x00660 , 0x00669 }, { 0x006f0 , 0x006f9 }, { 0x007c0 , 0x007c9 }, { 0x00966 , 0x0096f },
{ 0x009e6 , 0x009ef }, { 0x00a66 , 0x00a6f }, { 0x00ae6 , 0x00aef }, { 0x00b66 , 0x00b6f }, { 0x00be6 , 0x00bef },
{ 0x00c66 , 0x00c6f }, { 0x00ce6 , 0x00cef }, { 0x00d66 , 0x00d6f }, { 0x00e50 , 0x00e59 }, { 0x00ed0 , 0x00ed9 },
{ 0x00f20 , 0x00f29 }, { 0x01040 , 0x01049 }, { 0x017e0 , 0x017e9 }, { 0x01810 , 0x01819 }, { 0x01946 , 0x0194f },
{ 0x019d0 , 0x019d9 }, { 0x01b50 , 0x01b59 }, { 0x0ff10 , 0x0ff19 },
// Nl values length 5 index 23
{ 0x016ee , 0x016f0 }, { 0x02160 , 0x02182 }, { 0x03007, 0x03007 }, { 0x03021 , 0x03029}, { 0x03038 , 0x0303a }
};
template < int _index, int _length >
struct BaseIndex : public Base< 0 >
{
static const Value * v;
static const int length;
};
template < int _index, int _length >
const typename BaseIndex< _index, _length >::Value * BaseIndex< _index, _length >::v = &Base::v[ _index ];
template < int _index, int _length >
const int BaseIndex< _index, _length >::length = _length;
struct Nd : public BaseIndex< 0, 23 >
{
};
struct Nl : public BaseIndex< 23, 5 >
{
};
I think just a typedef in the namespace can replace those struct's Nd and Nl.
If there's a better way, I'm still open to suggestions.
This is my first attempt at couchbase. My json doc looks like this:
{
"member_id": "12345",
"devices": [
{
"device_id": "1",
"hashes": [
"h1",
"h2",
"h3",
"h4"
]
},
{
"device_id": "2",
"hashes": [
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"h7"
]
}
]
}
I want to create a view which tells me all member_ids for a given hash.
Something like this:
h1["12345","233","2323"] //233,2323 are other member id
h2["12345"]
The member_id should appear once in the set.
I wrote a map function
function (doc, meta) {
for(i=0;i< doc.devices.length;i++)
{
for(j=0;j< doc.devices[i].hashes.length;j++) {
emit(doc.devices[i].hashes[j],null)
}
}
}
and this returns
h1 "12345"
h1 "12345"
h2 "12345"
h1 "233"
but I'm not able to move forward from here. How should I change my map function to reduce the result?
Map function. Mostly yours, but emits meta.id as a value.
function(doc, meta) {
for(i=0; i< doc.devices.length; i++) {
for(j=0; j< doc.devices[i].hashes.length; j++) {
emit(doc.devices[i].hashes[j], meta.id)
}
}
}
Reduce function. Is just return unique array from values (taken from https://stackoverflow.com/a/13486540/98509)
function(keys, values, rereduce) {
return values.filter(function (e, i, arr) {
return arr.lastIndexOf(e) === i;
});
}
The following is an example of a multi-dimensional array declaration in C#:
var Number = new double[2, 3, 5]
{
{
{ 12.44, 525.38, -6.28, 2448.32, 632.04 },
{-378.05, 48.14, 634.18, 762.48, 83.02 },
{ 64.92, -7.44, 86.74, -534.60, 386.73 }
},
{
{ 48.02, 120.44, 38.62, 526.82, 1704.62 },
{ 56.85, 105.48, 363.31, 172.62, 128.48 },
{ 906.68, 47.12, -166.07, 4444.26, 408.62 }
},
};
I would like to do the same in C++, but do not know how and have not read my C++ book.
How can I accomplish this?
Here is a naive way of doing that without explicitly specifying the bounds:
vector<vector<vector<double>>> v =
{
{
{ 12.44, 525.38, -6.28, 2448.32, 632.04 },
{-378.05, 48.14, 634.18, 762.48, 83.02 },
{ 64.92, -7.44, 86.74, -534.60, 386.73 }
},
{
{ 48.02, 120.44, 38.62, 526.82, 1704.62 },
{ 56.85, 105.48, 363.31, 172.62, 128.48 },
{ 906.68, 47.12, -166.07, 4444.26, 408.62 }
},
};
However, the vector of vectors will allow you to push elements into each dimension freely (they are just independent vectors), so you might end up not having a consistent multi-dimensional vector. In particular, the compiler won't detect any attempt to put more or less elements into one dimension than into another one.
If that is a concern, you might want to check Boost.MultiArray.
You don't need the standard library, or Boost, to define and initialize a fixed size multidimensional array.
double Number[2][3][5] =
{
{
{ 12.44, 525.38, -6.28, 2448.32, 632.04 },
{-378.05, 48.14, 634.18, 762.48, 83.02 },
{ 64.92, -7.44, 86.74, -534.60, 386.73 }
},
{
{ 48.02, 120.44, 38.62, 526.82, 1704.62 },
{ 56.85, 105.48, 363.31, 172.62, 128.48 },
{ 906.68, 47.12, -166.07, 4444.26, 408.62 }
},
};