Updated Spiral Topography (markdown)

Michael Miller
2017-01-09 12:47:13 -08:00
parent fc7fbb535a
commit 1ee3b15aa3

@@ -34,19 +34,19 @@ uint16_t Map(int16_t ring, int16_t pixel) const {
return index;
}
```
This can be improved by checking boundary cases. As it sits if you call it with ring 0 but state pixel #32 which doesn't make sense; it will return a value that is possibly out of scope.
This can be improved by checking boundary cases. As it sits if you call it with ring 0 but state pixel #32 which doesn't make sense. It may also return a value that is possibly out of scope.
Below I have added the argument checking code. The ring table has been expanded to include an extra ring valueas it provides us with the information to be able to validate the arguments.
Below I have added the argument checking code. The ring table has been expanded to include an extra ring valueas as it will provide us with the information to be able to validate the arguments.
```
const uint16_t Rings[] = {0, 1, 7, 19, 35, 59, 119}; // note, included the start of another ring
uint16_t Map(uint16_t ring, uint16_t pixel) const {
if (ring >= (sizeof(Rings)/sizeof(Rings[0]) - 1)) { // minus one as the Rings includes the extra value
return 0; // invalid ring argument
return 0; // invalid ring argument, always return the first one
}
if (pixel >= Rings[ring + 1]) { // using the extra value for range testing
return 0; // invalid pixel argument
if (pixel >= (Rings[ring + 1] - Rings[ring]) { // using the extra value for range testing
return 0; // invalid pixel argument, always return the first one
}
uint16_t index = Rings[ring] + pixel;
return index;
@@ -55,4 +55,66 @@ uint16_t Map(uint16_t ring, uint16_t pixel) const {
NOTE: The code above `(sizeof(Rings)/sizeof(Rings[0])` is a way of having the compiler calculate the count of elements in the Rings array without us hardcoding anything. Often this is exposed as `_countof()` in many code bases but it was not included in the Arduino headers for some reason.
### Making the object usable for different collections of rings
The above code hard codes the array of values. We can make this a configuration argument to the constructor of our mapping class and thus reuse the code for different projects.
The above code uses a constant array of values directly. We can make this a configuration argument to the constructor of our mapping class and thus reuse the code for different projects. To do this, it and its count of elements must be past to the constructor and stored in member variables.
```
class NeoSpiralTopology {
public:
NeoSpiralTopology(const uint16_t* rings, uint8_t ringsCount) :
_rings(rings),
_ringsCount(ringsCount) {}
private:
const uint16_t* _rings;
const uint8_t _ringsCount;
}
```
and the code to initialize it would be
```
const uint16_t Rings[] = {0, 1, 7, 19, 35, 59, 119}; // required, include the start of another ring
NeoSpiralTopology topo(Rings, sizeof(Rings) / sizeof(Rings[0]));
```
### And the Final NeoSpiralTopology class is
Merge and modify the code above into one class and you get...
```
class NeoSpiralTopology {
public:
NeoSpiralTopology(const uint16_t* rings, uint8_t ringsCount) :
_rings(rings),
_ringsCount(ringsCount) {}
uint16_t Map(uint16_t ring, uint16_t pixel) const {
if (ring >= getCountOfRings()) {
return 0; // invalid ring argument, always return a valid value, the first one
}
if (pixel >= getPixelCountAtRing(ring)) {
return 0; // invalid pixel argument, always return a valid value, the first one
}
return _map(ring, pixel);
}
uint16_t MapProbe(uint16_t ring, uint16_t pixel) const
{
if (ring >= getCountOfRings() || pixel >= getPixelCountAtRing(ring)) {
return _rings[_ringsCount - 1]; // total count, the last entry, out of bounds
}
return _map(ring, pixel);
}
uint16_t getCountOfRings() const {
return _ringsCount - 1; // minus one as the Rings includes the extra value
}
uint16_t getPixelCountAtRing(uint16_t ring) const {
return Rings[ring + 1] - Rings[ring]; // using the extra value for count calc
}
private:
const uint16_t* _rings;
const uint8_t _ringsCount;
uint16_t _map(uint16_t ring, uint16_t pixel) {
return _rings[ring] + pixel;
}
}
```