updated libraries
This commit is contained in:
parent
d5d5d000b3
commit
3b7e68065a
102 changed files with 3020 additions and 1624 deletions
|
|
@ -17,6 +17,19 @@
|
|||
#include "fl/hash_set.h"
|
||||
#include "fl/vector.h"
|
||||
|
||||
// Define an improved CHECK_CLOSE macro that provides better error messages
|
||||
#define CHECK_CLOSE(a, b, epsilon) \
|
||||
do { \
|
||||
float _a = (a); \
|
||||
float _b = (b); \
|
||||
float _diff = fabsf(_a - _b); \
|
||||
bool _result = _diff <= (epsilon); \
|
||||
if (!_result) { \
|
||||
printf("CHECK_CLOSE failed: |%f - %f| = %f > %f\n", (float)_a, \
|
||||
(float)_b, _diff, (float)(epsilon)); \
|
||||
} \
|
||||
CHECK(_result); \
|
||||
} while (0)
|
||||
|
||||
using namespace fl;
|
||||
|
||||
|
|
@ -80,9 +93,9 @@ namespace doctest {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct StringMaker<fl::vector<T>> {
|
||||
static String convert(const fl::vector<T>& value) {
|
||||
template<typename T, typename Alloc>
|
||||
struct StringMaker<fl::vector<T, Alloc>> {
|
||||
static String convert(const fl::vector<T, Alloc>& value) {
|
||||
fl::Str out;
|
||||
out.append(value);
|
||||
return out.c_str();
|
||||
|
|
|
|||
|
|
@ -2,138 +2,119 @@
|
|||
|
||||
#include "fl/math_macros.h"
|
||||
#include "test.h"
|
||||
#include "fl/algorithm.h"
|
||||
|
||||
#include "fl/sstream.h"
|
||||
|
||||
#include "fl/corkscrew.h"
|
||||
|
||||
#include "fl/grid.h"
|
||||
#include "fl/tile2x2.h" // Ensure this header is included for Tile2x2_u8
|
||||
|
||||
#define NUM_LEDS 288
|
||||
|
||||
|
||||
#define TWO_PI (PI * 2.0)
|
||||
|
||||
// Define an improved CHECK_CLOSE macro that provides better error messages
|
||||
#define CHECK_CLOSE(a, b, epsilon) \
|
||||
do { \
|
||||
float _a = (a); \
|
||||
float _b = (b); \
|
||||
float _diff = fabsf(_a - _b); \
|
||||
bool _result = _diff <= (epsilon); \
|
||||
if (!_result) { \
|
||||
printf("CHECK_CLOSE failed: |%f - %f| = %f > %f\n", (float)_a, \
|
||||
(float)_b, _diff, (float)(epsilon)); \
|
||||
} \
|
||||
CHECK(_result); \
|
||||
} while (0)
|
||||
|
||||
using namespace fl;
|
||||
|
||||
TEST_CASE("Corkscrew generateMap") {
|
||||
TEST_CASE("Corkscrew Circle10 test") {
|
||||
Corkscrew::Input input;
|
||||
input.totalHeight = 10.0f;
|
||||
input.totalAngle = TWO_PI;
|
||||
input.offsetCircumference = 0.0f;
|
||||
input.numLeds = 10;
|
||||
|
||||
Corkscrew::Output output = Corkscrew::generateMap(input);
|
||||
|
||||
CHECK_EQ(output.width, 10);
|
||||
CHECK_EQ(output.height, 1); // One vertical segment for one turn
|
||||
CHECK_EQ(output.mapping.size(), 10); // 10 LEDs around the corkscrew
|
||||
|
||||
CHECK_GE(output.mapping[0].x, 0.0f);
|
||||
CHECK_LE(output.mapping[0].x, 10.0f);
|
||||
CHECK_GE(output.mapping[0].y, 0.0f);
|
||||
CHECK_LE(output.mapping[0].y, 1.0f); // 1 vertical segment for 2π angle
|
||||
}
|
||||
|
||||
TEST_CASE("Corkscrew to Frame Buffer Mapping") {
|
||||
// Define the corkscrew input parameters
|
||||
|
||||
|
||||
|
||||
const int kCorkscrewTotalHeight = 1; // cm
|
||||
//const int CORKSCREW_WIDTH = 1; // Width of the corkscrew in pixels
|
||||
//const int CORKSCREW_HEIGHT = 1; // Height of the corkscrew in pixels
|
||||
const int kCorkscrewTurns = 2; // Default to 19 turns
|
||||
|
||||
|
||||
|
||||
Corkscrew::Input input;
|
||||
input.totalHeight = kCorkscrewTotalHeight;
|
||||
input.totalAngle = kCorkscrewTurns * 2 * PI; // Default to 19 turns
|
||||
input.offsetCircumference = 0.0f;
|
||||
input.numLeds = 3;
|
||||
|
||||
// Generate the corkscrew map
|
||||
|
||||
|
||||
|
||||
Corkscrew corkscrew(input);
|
||||
|
||||
volatile Corkscrew::Output* output = &corkscrew.access();
|
||||
|
||||
// vec2<int16_t> first = corkscrew.at(0);
|
||||
// vec2<int16_t> second = corkscrew.at(1);
|
||||
|
||||
Corkscrew::iterator it = corkscrew.begin();
|
||||
Corkscrew::iterator end = corkscrew.end();
|
||||
|
||||
fl::sstream ss;
|
||||
ss << "\n";
|
||||
ss << "width: " << output->width << "\n";
|
||||
ss << "height: " << output->height << "\n";
|
||||
|
||||
while (it != end) {
|
||||
ss << *it << "\n";
|
||||
++it;
|
||||
}
|
||||
|
||||
FASTLED_WARN(ss.str());
|
||||
|
||||
|
||||
MESSAGE("done");
|
||||
input.totalLength = 10.0f; // Total length of the corkscrew in centimeters
|
||||
input.totalHeight = 0.0f;
|
||||
input.totalTurns = 1.0f;
|
||||
input.offsetCircumference = 0.0f; // No offset
|
||||
input.numLeds = 10; // Default to dense 144 LEDs times two strips
|
||||
Corkscrew::State output = Corkscrew::generateState(input);
|
||||
fl::vector<vec2f> expected_values;
|
||||
expected_values.push_back(vec2f(0.0f, 0.0f)); // First LED at the bottom
|
||||
expected_values.push_back(vec2f(1.0f, 0.0f)); // Second LED in the middle
|
||||
expected_values.push_back(vec2f(2.0f, 0.0f)); // Third LED at the top
|
||||
expected_values.push_back(vec2f(3.0f, 0.0f)); // Fourth LED at the top
|
||||
expected_values.push_back(vec2f(4.0f, 0.0f)); // Fifth LED at the top
|
||||
expected_values.push_back(vec2f(5.0f, 0.0f)); // Sixth LED at the top
|
||||
expected_values.push_back(vec2f(6.0f, 0.0f)); // Seventh LED at the top
|
||||
expected_values.push_back(vec2f(7.0f, 0.0f)); // Eighth LED at the top
|
||||
expected_values.push_back(vec2f(8.0f, 0.0f)); // Ninth LED at the top
|
||||
expected_values.push_back(vec2f(9.0f, 0.0f)); // Tenth LED at the top
|
||||
|
||||
REQUIRE_EQ(output.width, 10);
|
||||
REQUIRE_EQ(output.height, 1);
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Corkscrew generateMap with two turns") {
|
||||
Corkscrew::Input input;
|
||||
input.totalHeight = 10.0f;
|
||||
input.totalAngle = 2 * TWO_PI; // Two full turns
|
||||
input.numLeds = 10; // 10 LEDs around the corkscrew
|
||||
input.offsetCircumference = 0.0f;
|
||||
TEST_CASE("Tile2x2_u8_wrap wrap-around test with width and height") {
|
||||
// Initialize a Tile2x2_u8 with known values and set origin beyond boundaries
|
||||
Tile2x2_u8 originalTile;
|
||||
originalTile.setOrigin(3, 3); // Set the origin beyond the width and height
|
||||
originalTile.at(0, 0) = 1;
|
||||
originalTile.at(0, 1) = 2;
|
||||
originalTile.at(1, 0) = 3;
|
||||
originalTile.at(1, 1) = 4;
|
||||
|
||||
Corkscrew::Output output = Corkscrew::generateMap(input);
|
||||
// Convert to Tile2x2_u8_wrap with given width and height
|
||||
uint16_t width = 2;
|
||||
uint16_t height = 2;
|
||||
Tile2x2_u8_wrap cycTile(originalTile, width, height);
|
||||
|
||||
CHECK_EQ(output.width, 5);
|
||||
CHECK_EQ(output.height, 2); // Two vertical segments for two turns
|
||||
CHECK_EQ(output.mapping.size(), 10); // 5 width * 2 height
|
||||
// Verify that the conversion wraps around correctly
|
||||
REQUIRE_EQ(cycTile.at(0, 0).first.x, 1); // Wraps around to (1, 1)
|
||||
REQUIRE_EQ(cycTile.at(0, 0).first.y, 1);
|
||||
REQUIRE_EQ(cycTile.at(0, 1).first.x, 1); // Wraps around to (1, 0)
|
||||
REQUIRE_EQ(cycTile.at(0, 1).first.y, 0);
|
||||
REQUIRE_EQ(cycTile.at(1, 0).first.x, 0); // Wraps around to (0, 1)
|
||||
REQUIRE_EQ(cycTile.at(1, 0).first.y, 1);
|
||||
REQUIRE_EQ(cycTile.at(1, 1).first.x, 0); // Wraps around to (0, 0)
|
||||
REQUIRE_EQ(cycTile.at(1, 1).first.y, 0);
|
||||
|
||||
// Check first pixel for correctness (basic integrity)
|
||||
CHECK_GE(output.mapping[0].x, 0.0f);
|
||||
CHECK_LE(output.mapping[0].x, 5.0f);
|
||||
CHECK_GE(output.mapping[0].y, 0.0f);
|
||||
CHECK_LE(output.mapping[0].y, 2.0f); // 2 vertical segments for 4π angle
|
||||
// Verify that the values are correct
|
||||
REQUIRE_EQ(cycTile.at(0, 0).second, 1);
|
||||
REQUIRE_EQ(cycTile.at(0, 1).second, 2);
|
||||
REQUIRE_EQ(cycTile.at(1, 0).second, 3);
|
||||
REQUIRE_EQ(cycTile.at(1, 1).second, 4);
|
||||
}
|
||||
|
||||
TEST_CASE("Corkscrew circumference test") {
|
||||
Corkscrew::Input input;
|
||||
// Use defaults: totalHeight = 100, totalAngle = 19 * 2 * PI
|
||||
input.totalHeight = 23.25f; // Total height of the corkscrew in centimeters
|
||||
input.totalAngle = 19.0f * TWO_PI; // Default to 19 turns
|
||||
input.offsetCircumference = 0.0f; // No offset
|
||||
input.numLeds = 288; // Default to dense 144 LEDs times two strips
|
||||
TEST_CASE("Tile2x2_u8_wrap conversion with width and height") {
|
||||
// Initialize a Tile2x2_u8 with known values
|
||||
Tile2x2_u8 originalTile;
|
||||
originalTile.setOrigin(0, 0); // Set the origin to (0, 0)
|
||||
originalTile.at(0, 0) = 1;
|
||||
originalTile.at(0, 1) = 2;
|
||||
originalTile.at(1, 0) = 3;
|
||||
originalTile.at(1, 1) = 4;
|
||||
|
||||
Corkscrew::Output output = Corkscrew::generateMap(input);
|
||||
// Convert to Tile2x2_u8_wrap with given width and height
|
||||
uint16_t width = 2;
|
||||
uint16_t height = 2;
|
||||
Tile2x2_u8_wrap cycTile(originalTile, width, height);
|
||||
|
||||
// Basic sanity checks
|
||||
CHECK_EQ(output.width, 16);
|
||||
CHECK_EQ(output.height, 19);
|
||||
CHECK_EQ(output.mapping.size(), 288);
|
||||
|
||||
// Check that circumference matches calculated value
|
||||
// float expectedCircumference = 100.0f / 19.0f;
|
||||
// CHECK_CLOSE(output.circumference, expectedCircumference, 0.01f);
|
||||
// Verify that the conversion is correct
|
||||
REQUIRE_EQ(cycTile.at(0, 0).second, 1);
|
||||
REQUIRE_EQ(cycTile.at(0, 1).second, 2);
|
||||
REQUIRE_EQ(cycTile.at(1, 0).second, 3);
|
||||
REQUIRE_EQ(cycTile.at(1, 1).second, 4);
|
||||
}
|
||||
|
||||
TEST_CASE("Tile2x2_u8_wrap conversion test") {
|
||||
// Initialize a Tile2x2_u8 with known values and a specific origin
|
||||
Tile2x2_u8 originalTile;
|
||||
originalTile.setOrigin(50, 50); // Set the origin to (50, 50)
|
||||
originalTile.at(0, 0) = 1; // Initialize the missing element
|
||||
originalTile.at(0, 1) = 2;
|
||||
originalTile.at(1, 0) = 3;
|
||||
originalTile.at(1, 1) = 4;
|
||||
|
||||
// Convert to Tile2x2_u8_wrap with a given width
|
||||
uint16_t width = 10;
|
||||
Tile2x2_u8_wrap cycTile(originalTile, width);
|
||||
|
||||
// Verify that the conversion is correct
|
||||
REQUIRE_EQ(cycTile.at(0, 0).second, 1);
|
||||
REQUIRE_EQ(cycTile.at(0, 1).second, 2);
|
||||
REQUIRE_EQ(cycTile.at(1, 0).second, 3);
|
||||
REQUIRE_EQ(cycTile.at(1, 1).second, 4);
|
||||
|
||||
// Verify wrap-around behavior on the x-axis
|
||||
REQUIRE_EQ(cycTile.at(2, 2).second, 1); // Wraps around to (0, 0)
|
||||
REQUIRE_EQ(cycTile.at(2, 3).second, 2); // Wraps around to (0, 1)
|
||||
REQUIRE_EQ(cycTile.at(3, 2).second, 3); // Wraps around to (1, 0)
|
||||
REQUIRE_EQ(cycTile.at(3, 3).second, 4); // Wraps around to (1, 1)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue