add some code

This commit is contained in:
2025-09-05 13:25:11 +08:00
parent 9ff0a99e7a
commit 3cf1229a85
8911 changed files with 2535396 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
**/build/
**/sdkconfig
**/sdkconfig.old
**/dependencies.lock
**/managed_components/**

View File

@@ -0,0 +1,29 @@
# ESP-DSP ESP32-Azure IoT kit demo applications
The demo applications are developed for ESP32-Azure IoT kit development board and are demonstrating usage of matrices with ESP-DPS Mat class, Kalman filter and basic
3D projection with matrices
### [3D Graphics demo](apps/3d_graphics)
* a simple rotation of a selected 3D objects is shown on the display
* demonstrating usage the Mat class, matrices and operations with matrices
<div align="center">
<img src= "apps/3d_graphics/3d_graphics.gif">
</div>
### [Kalman filter demo](apps/kalman_filter/)
* a selected 3D object is following movements of the development board with IMU sensors
* the sensors outputs are processed by the Kalman filter
* demonstrating usage the Mat class, matrices, operations with matrices and Kalman filter
<div align="center">
<img src= "apps/kalman_filter/kalman_filter.gif">
</div>
### [3D graphics](graphics/img_to_3d_matrix/example/)
Simple 3D graphics is used in the both demos, to display the 3D on the monochromatic display. The Graphics is using transformation matrices to rotate, scale and translate (move) 3D objects, to show the matrix calculation capabilities of the ESP-DSP repository.
## Used components
* [ESP-DSP](https://github.com/espressif/esp-dsp): matrices, Mat class, Kalman filter
* [ESP-BSP](https://github.com/espressif/esp-bsp): ESP32-Azure IoT kit

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
add_compile_options("-Wno-format")
project(esp-dsp-azure-board-app-3d-graphics)

View File

@@ -0,0 +1,27 @@
# ESP-DSP ESP32-Azure IoT kit 3d graphics demo application
The demo is developed for [ESP32-Azure IoT kit](https://github.com/espressif/esp-bsp/tree/master/esp32_azure_iot_kit) development board and is demonstrating the usage of matrices with `ESP-DSP` `Mat` class, Kalman filter and basic 3D graphics.
The 3D Graphics demo displays a 2D graphics, converted to 3D as a 3D rotating object, on the development board's display. Button press changes the rotation direction of the 3D object. Run the menuconfig using the following command:
idf.py mencuonfig
In the menuconfig's menu item `Demo user configuration` select which 3D object to display. It's either a 3D cube, or ESP logo, or a user-defined graphics. Getting the user-defined graphics is described in an [example](../../graphics/img_to_3d_matrix/example/)
## Running the demo
To start the demo, run the following command:
idf.py build flash monitor
The expected output is the following:
I (570) 3D image demo: Selected 3D image - ESP Logo
I (570) 3D image demo: Showing ESP text
I (6730) 3D image demo: Showing 3D image
Note, that the first line `Selected 3D image` from the expected output depends on the user's Kconfing menu selection
<div align="center">
<img src= "applications/azure_board_apps/apps/3d_graphics/3d_graphics.gif">
</div>

View File

@@ -0,0 +1,240 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include "esp_log.h"
#include "ssd1306.h"
#include "bsp/esp-bsp.h"
#include "esp_dsp.h"
#include "cube_matrix.h"
#include "esp_logo.h"
#include "esp_text.h"
#include "graphics_support.h"
#include "image_to_3d_matrix.h"
static ssd1306_handle_t ssd1306_dev = NULL;
static bool button_pressed = true;
dspm::Mat perspective_matrix(MATRIX_SIZE, MATRIX_SIZE);
extern "C" void app_main();
/**
* @brief Initialize 3d image structure
*
* Assigns a 3d image to be displayed to the 3d image structure based on the Kconfig menu result.
* The Kconfig menu is operated by a user
*
* @param image: 3d image structure
*/
static void init_3d_matrix_struct(image_3d_matrix_t *image)
{
#ifdef CONFIG_3D_OBJECT_ESP_LOGO
image->matrix = image_3d_matrix_esp_logo;
image->matrix_len = ((sizeof(image_3d_matrix_esp_logo)) / sizeof(float)) / MATRIX_SIZE;
ESP_LOGI("3D image demo", "Selected 3D image - ESP Logo");
#elif CONFIG_3D_OBJECT_CUSTOM
image->matrix = image_to_3d_matrix_custom;
image->matrix_len = ((sizeof(image_to_3d_matrix_custom)) / sizeof(float)) / MATRIX_SIZE;
ESP_LOGI("3D image demo", "Selected 3D image - User's custom image");
#elif CONFIG_3D_OBJECT_CUBE
image->matrix = cube_vectors_3d;
image->matrix_len = ((sizeof(cube_vectors_3d)) / sizeof(float)) / MATRIX_SIZE;
ESP_LOGI("3D image demo", "Selected 3D image - 3D cube");
#endif
}
/**
* @brief Initialize display
*/
static void app_ssd1306_init(void)
{
ssd1306_dev = ssd1306_create((i2c_port_t)BSP_I2C_NUM, SSD1306_I2C_ADDRESS);
ssd1306_clear_screen(ssd1306_dev, 0x00);
ssd1306_refresh_gram(ssd1306_dev);
}
/**
* @brief Display a 3d image
*
* If the object is the 3d cube, connect the projected cube points by lines and display the lines
* For any other 3d object lit pixels on the display from provided XY coordinates
*
* @param projected_image: 3d matrix from Mat class after projection
*/
static void display_3d_image(dspm::Mat projected_image)
{
ssd1306_clear_screen(ssd1306_dev, 0);
if (OBJECT_3D_CUBE) {
// For the 3D cube, only the 6 points of the cube are transformed
// Cube edges, connecting transformed 3D cube points are connected with lines here
for (uint8_t cube_point = 0; cube_point < CUBE_EDGES; cube_point++) {
ssd1306_draw_line(ssd1306_dev,
(int16_t)projected_image(cube_dict_line_begin[cube_point], 0),
(int16_t)projected_image(cube_dict_line_begin[cube_point], 1),
(int16_t)projected_image(cube_dict_line_end[cube_point], 0),
(int16_t)projected_image(cube_dict_line_end[cube_point], 1));
}
} else {
// Every other 3D image is drawn here pixel by pixel
for (uint32_t pixel = 0; pixel < projected_image.rows; pixel++ ) {
ssd1306_fill_point(ssd1306_dev, projected_image(pixel, 0), projected_image(pixel, 1), 1);
}
}
ssd1306_refresh_gram(ssd1306_dev);
}
/**
* @brief Display ESPRESSIF text
*
* To demonstrate usage of the translation and scaling matrices
*/
static void dispaly_esp_text(void)
{
image_3d_matrix_t esp_text;
esp_text.matrix = image_3d_array_esp_text;
esp_text.matrix_len = ((sizeof(image_3d_array_esp_text)) / sizeof(float)) / MATRIX_SIZE;
int16_t shift_x = -SSD1606_X_CENTER;
dspm::Mat T = dspm::Mat::eye(MATRIX_SIZE); // Transformation matrix
dspm::Mat transformed_image(esp_text.matrix_len, MATRIX_SIZE); // 3D image matrix after transformation
dspm::Mat matrix_3d((float *)esp_text.matrix[0], esp_text.matrix_len, MATRIX_SIZE);
ESP_LOGI("3D image demo", "Showing ESP text");
for (int i = 0; i < 52; i++) {
update_translation_matrix(T, true, (float)shift_x, (float)SSD1606_Y_CENTER, 0);
transformed_image = matrix_3d * T;
ssd1306_clear_screen(ssd1306_dev, 0);
for (uint32_t point = 0; point < transformed_image.rows; point++ ) {
ssd1306_fill_point(ssd1306_dev, transformed_image(point, 0), transformed_image(point, 1), 1);
}
ssd1306_refresh_gram(ssd1306_dev);
vTaskDelay(50 / portTICK_PERIOD_MS);
shift_x += 5;
}
ssd1306_clear_screen(ssd1306_dev, 0);
ssd1306_draw_bitmap(ssd1306_dev, 0, 24, &image_bmp_array_esp_text[0], 128, 24);
ssd1306_refresh_gram(ssd1306_dev);
update_translation_matrix(T, true, (float)SSD1606_X_CENTER, (float)SSD1606_Y_CENTER, 0);
vTaskDelay(100 / portTICK_PERIOD_MS);
float scale = 1;
for (int i = 0; i < 20; i++) {
update_scaling_matrix(T, false, scale, scale, 1);
transformed_image = matrix_3d * T;
ssd1306_clear_screen(ssd1306_dev, 0);
for (uint32_t point = 0; point < transformed_image.rows; point++ ) {
ssd1306_fill_point(ssd1306_dev, transformed_image(point, 0), transformed_image(point, 1), 1);
}
ssd1306_refresh_gram(ssd1306_dev);
vTaskDelay(50 / portTICK_PERIOD_MS);
if (i < 10) {
scale -= 0.05;
} else {
scale += 0.05;
}
}
}
/**
* @brief RTOS task to draw a 3d image.
*
* Updates 3d matrices, prepares the final 3d matrix to be displayed on the display
*
* @param arg: pointer to RTOS task arguments, 3d image structure in this case
*/
static void draw_3d_image_task(void *arg)
{
float rot_y = 0, rot_x = 0;
const float angle_increment = 4;
image_3d_matrix_t *image = (image_3d_matrix_t *)arg;
dspm::Mat T = dspm::Mat::eye(MATRIX_SIZE); // Transformation matrix
dspm::Mat transformed_image(image->matrix_len, MATRIX_SIZE); // 3D image matrix after transformation
dspm::Mat projected_image(image->matrix_len, MATRIX_SIZE); // 3D image matrix after projection
dspm::Mat matrix_3d((float *)image->matrix[0], image->matrix_len, MATRIX_SIZE);
if (OBJECT_3D_CUBE) {
rot_x = 45;
}
while (1) {
if (button_pressed) {
rot_y += angle_increment;
if (rot_y >= 360) {
rot_y -= 360;
}
} else {
rot_y -= angle_increment;
if (rot_y <= 0) {
rot_y += 360;
}
}
// Apply rotation in all the axes to the transformation matrix
update_rotation_matrix(T, rot_x, rot_y, 0);
// Apply translation to the transformation matrix
update_translation_matrix(T, true, ((float)SSD1606_X_CENTER), ((float)SSD1606_Y_CENTER), 0);
// explanation for the matrix multiplication is for the 3D cube scenario, applies for all of the objects
// where matrix rows for the transformed image and the projected image are set according to the specific 3d object
// matrix mul cube_matirx(8x4) * transformation_matrix(4x4) = transformed_cube(8x4)
transformed_image = matrix_3d * T;
// matrix mul transformed_cube(8x4) * perspective_matrix(4x4) = projected_cube(8x4)
projected_image = transformed_image * perspective_matrix;
display_3d_image(projected_image);
vTaskDelay(20 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
static bool button_prev_val = false;
image_3d_matrix_t image;
ekf_imu13states *ekf13 = new ekf_imu13states();
ekf13->Init();
// Init all board components
bsp_i2c_init();
app_ssd1306_init(); // display init
bsp_leds_init(); // LEDs init
bsp_i2c_set_clk_speed(I2C_CLK_600KHZ); // Set I2C to 600kHz
init_perspective_matrix(perspective_matrix);
init_3d_matrix_struct(&image);
dispaly_esp_text();
vTaskDelay(1000 / portTICK_PERIOD_MS);
xTaskCreate(draw_3d_image_task, "draw_3d_image", 2048, &image, 4, NULL);
ESP_LOGI("3D image demo", "Showing 3D image");
while (1) {
if (bsp_button_get()) {
button_pressed = !button_pressed;
}
if (button_prev_val != button_pressed) {
button_prev_val = button_pressed;
if (button_pressed) {
bsp_led_set(BSP_LED_AZURE, true);
} else {
bsp_led_set(BSP_LED_AZURE, false);
}
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}

View File

@@ -0,0 +1,8 @@
idf_component_register(SRCS "3d_graphics_demo.cpp"
"../../../graphics/3d_matrix/3d_matrix_data/esp_logo.c"
"../../../graphics/3d_matrix/3d_matrix_data/esp_text.c"
"../../../graphics/3d_matrix/3d_matrix_data/image_to_3d_matrix.c"
"../../../graphics/3d_matrix/3d_matrix_src/graphics_support.cpp"
INCLUDE_DIRS "."
"../../../graphics/3d_matrix/3d_matrix_data"
"../../../graphics/3d_matrix/3d_matrix_src")

View File

@@ -0,0 +1,19 @@
menu "Demo user configuration"
choice
prompt "Select 3D object"
config 3D_OBJECT_CUBE
bool "3D cube"
help
3D graphics to be displayed is cube
config 3D_OBJECT_ESP_LOGO
bool "3D ESP Logo"
help
3D graphics to be displayed is ESP Logo
config 3D_OBJECT_CUSTOM
bool "User-defined graphics"
help
3D graphics to be displayed is a user-defined graphics
endchoice
endmenu

View File

@@ -0,0 +1,8 @@
## IDF Component Manager Manifest File
description: ESP-DSP azure board application 3d graphics
dependencies:
espressif/esp32_azure_iot_kit: "*"
espressif/esp-dsp:
version: "*"
override_path: "../../../../../../esp-dsp"

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
add_compile_options("-Wno-format")
project(esp-dsp-azure-board-app-kalman-filter)

View File

@@ -0,0 +1,59 @@
# ESP-DSP ESP32-Azure IoT kit Kalman filter demo application
The demo is developed for [ESP32-Azure IoT kit](https://github.com/espressif/esp-bsp/tree/master/esp32_azure_iot_kit) development board and is demonstrating the usage of matrices with `ESP-DSP` `Mat` class, Kalman filter and basic 3D graphics.
The Kalman filter demo displays a 2D graphics, converted to 3D as a 3D object, on the development board's display. The 3D object follows the movements of the development board, where the Kalman filter is used for processing the output signals of the IMU sensors accommodated on the development board. The 3D object rotation is calculated by the Kalman filter class methods. All 3 IMU sensors present on the dev board (accelerometer, gyroscope and magnetometer) are used for sensing the development board's position.
If the board is inactive (no, or very low rotation is detected) for a set period of time, the demo enters an "Idle" state, in which a 3D rotating object is displayed. Once a certain set level of the board's rotation is detected, the demo enters a normal, "Active", state.
For the project settings, run the menuconfig using the following command:
idf.py mencuonfig
In the menuconfig's menu item `Demo user configuration` select which 3D object to display. It's either 3D cube, or ESP logo, or a user-defined graphics. Getting the user-defined 3D object is described in the [3D Graphics demo](../3d_graphics)
## Kalman filter
#### Calibration
The filter must be calibrated before the first run, which takes several minutes. But the calibration process before each run can be omitted by calibrating the filter once, saving Kalman's filter state vectors to the NVS, and loading those vectors back into the Kalman filter before the run. In addition, every 5 minutes a current state vectors are saved into the flash memory.
## Running the demo
To start the demo, run the following command:
idf.py build flash monitor
The expected output is the following:
I (589) Kalman filter demo: Selected 3D image - 3D cube
I (590) Kalman filter demo: Filter state vectors present in the NVS
I (592) Kalman filter demo: Loading state vectors into the filter structure
I (604) Kalman filter demo: State vectors loaded from the NVS
I (606) Barometer: disabled
I (619) Board status: board put to active mode
I (95780) Board status: board put to idle mode
I (300619) Kalman filter demo: State vectors saved to NVS
Note, that the first line `Selected 3D image` from the expected output depends on the user's Kconfing menu selection
To start the demo and run the initial Kalman filter calibration, one must erase the flash memory, to remove the previously stored Kalman filter's state vectors. To do so, run the following command:
idf.py erase_flash build flash monitor
The expected output is the following:
I (592) Kalman filter demo: Selected 3D image - 3D cube
I (595) Kalman filter demo: Filter state vectors not present in the NVS
I (595) Kalman filter demo: Starting Kalman filter calibration loop
I (100699) Kalman filter demo: Exiting Kalman filter calibration loop
I (100894) Kalman filter demo: Estimated gyroscope bias error [deg/sec]: -0.020715 -0.000431 -0.022452
I (100900) Kalman filter demo: State vectors saved to the NVS
I (100900) Barometer: disabled
I (100911) Board status: board put to active mode
I (196072) Board status: board put to idle mode
I (400912) Kalman filter demo: State vectors saved to NVS
<div align="center">
<img src= "applications/azure_board_apps/apps/kalman_filter/kalman_filter.gif">
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

View File

@@ -0,0 +1,7 @@
idf_component_register(SRCS "kalman_filter_demo.cpp"
"../../../graphics/3d_matrix/3d_matrix_data/esp_logo.c"
"../../../graphics/3d_matrix/3d_matrix_data/image_to_3d_matrix.c"
"../../../graphics/3d_matrix/3d_matrix_src/graphics_support.cpp"
INCLUDE_DIRS "."
"../../../graphics/3d_matrix/3d_matrix_data"
"../../../graphics/3d_matrix/3d_matrix_src")

View File

@@ -0,0 +1,19 @@
menu "Demo user configuration"
choice
prompt "Select 3D object"
config 3D_OBJECT_CUBE
bool "3D cube"
help
3D graphics to be displayed is cube
config 3D_OBJECT_ESP_LOGO
bool "3D ESP Logo"
help
3D graphics to be displayed is ESP Logo
config 3D_OBJECT_CUSTOM
bool "User-defined graphics"
help
3D graphics to be displayed is a user-defined graphics
endchoice
endmenu

View File

@@ -0,0 +1,8 @@
## IDF Component Manager Manifest File
description: ESP-DSP azure board application Kalman filter
dependencies:
espressif/esp32_azure_iot_kit: "*"
espressif/esp-dsp:
version: "*"
override_path: "../../../../../../esp-dsp"

View File

@@ -0,0 +1,608 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <malloc.h>
#include "mpu6050.h"
#include "ssd1306.h"
#include "mag3110.h"
#include "fbm320.h"
#include "bsp/esp-bsp.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "esp_idf_version.h" // for backward compatibility of esp-timer
#include "nvs.h"
#include "nvs_flash.h"
#include "graphics_support.h"
#include "cube_matrix.h"
#include "esp_dsp.h"
#include "ekf_imu13states.h"
#include "esp_logo.h"
#include "image_to_3d_matrix.h"
#define STORAGE_NAMESPACE "kalman_filter"
#define USE_BAROMETER 0
static ssd1306_handle_t ssd1306_dev = NULL;
static mpu6050_handle_t mpu6050_dev = NULL;
static mag3110_handle_t mag3110_dev = NULL;
static fbm320_handle_t fbm320_dev = NULL;
static bool kalman_filter_calibrated = false;
static bool board_inactive = true;
dspm::Mat perspective_matrix(MATRIX_SIZE, MATRIX_SIZE);
extern "C" void app_main();
/**
* @brief Initialize magnetometer
*/
static void app_mag3110_init(void)
{
esp_err_t ret;
mag3110_dev = mag3110_create((i2c_port_t)BSP_I2C_NUM);
mag3110_start_raw(mag3110_dev, MAG3110_DR_OS_80_16);
assert(ESP_OK == ret);
}
/**
* @brief Initialize display
*/
static void app_ssd1306_init(void)
{
ssd1306_dev = ssd1306_create((i2c_port_t)BSP_I2C_NUM, SSD1306_I2C_ADDRESS);
ssd1306_clear_screen(ssd1306_dev, 0x00);
ssd1306_refresh_gram(ssd1306_dev);
}
/**
* @brief Initialize accelerometer and gyroscope
*/
static void mpu6050_init(void)
{
esp_err_t ret;
mpu6050_dev = mpu6050_create((i2c_port_t)BSP_I2C_NUM, MPU6050_I2C_ADDRESS);
ret = mpu6050_config(mpu6050_dev, ACCE_FS_8G, GYRO_FS_2000DPS);
assert(ESP_OK == ret);
ret = mpu6050_wake_up(mpu6050_dev);
assert(ESP_OK == ret);
}
/**
* @brief Initialize pressure sensor
*/
static void app_fbm320_init(void)
{
esp_err_t ret;
fbm320_dev = fbm320_create((i2c_port_t)BSP_I2C_NUM, FBM320_I2C_ADDRESS_1);
ret = fbm320_init(fbm320_dev);
assert(ESP_OK == ret);
}
/**
* @brief Initialize NVS flash memory
*/
static void init_nvs_flash_memory(void)
{
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
// NVS partition was truncated and needs to be erased
// Retry nvs_flash_init
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK( err );
}
/**
* @brief Initialize 3d image structure
*
* Assigns a 3d image to be displayed to the 3d image structure based on the Kconfig menu result.
* The Kconfig menu is operated by a user
*
* @param image: pointer to 3d image structure
* @param ekf13: kalman filter object
*/
static void init_3d_matrix_struct(image_3d_matrix_kalman_t *image, ekf_imu13states *ekf13)
{
#ifdef CONFIG_3D_OBJECT_ESP_LOGO
image->matrix = image_3d_matrix_esp_logo;
image->matrix_len = ((sizeof(image_3d_matrix_esp_logo)) / sizeof(float)) / MATRIX_SIZE;
ESP_LOGI("Kalman filter demo", "Selected 3D image - ESP Logo");
#elif CONFIG_3D_OBJECT_CUSTOM
image->matrix = image_to_3d_matrix_custom;
image->matrix_len = ((sizeof(image_to_3d_matrix_custom)) / sizeof(float)) / MATRIX_SIZE;
ESP_LOGI("Kalman filter demo", "Selected 3D image - User's custom image");
#elif CONFIG_3D_OBJECT_CUBE
image->matrix = cube_vectors_3d;
image->matrix_len = ((sizeof(cube_vectors_3d)) / sizeof(float)) / MATRIX_SIZE;
ESP_LOGI("Kalman filter demo", "Selected 3D image - 3D cube");
#endif
image->ekf13 = ekf13;
}
/**
* @brief Display a 3d image
*
* If the object is the 3d cube, connect the projected cube points by lines and display the lines
* For any other 3d object lit pixels on the display from provided XY coordinates
*
* @param projected_image: 3d matrix from Mat class after projection
*/
static void display_3d_image(dspm::Mat projected_image)
{
ssd1306_clear_screen(ssd1306_dev, 0);
if (OBJECT_3D_CUBE) {
// For the 3D cube, only the 6 points of the cube are transformed
// Cube edges, connecting transformed 3D cube points are connected with lines here
for (uint8_t cube_point = 0; cube_point < CUBE_EDGES; cube_point++) {
ssd1306_draw_line(ssd1306_dev,
(int16_t)projected_image(cube_dict_line_begin[cube_point], 0),
(int16_t)projected_image(cube_dict_line_begin[cube_point], 1),
(int16_t)projected_image(cube_dict_line_end[cube_point], 0),
(int16_t)projected_image(cube_dict_line_end[cube_point], 1));
}
} else {
// Every other 3D image is drawn here pixel by pixel
for (uint32_t pixel = 0; pixel < projected_image.rows; pixel++ ) {
ssd1306_fill_point(ssd1306_dev, projected_image(pixel, 0), projected_image(pixel, 1), 1);
}
}
ssd1306_refresh_gram(ssd1306_dev);
}
/**
* @brief Draw a 3d image
*
* Updates 3d matrices and prepares the final 3d matrix to be displayed on the display.
* Board inactivity check - decides which board mode to display (active or inactive), based on the board movements.
*
* @param ekf13: kalman filter object
* @param transformed_image: 3d matrix holding a 3d image after transformation
* @param projected_image: 3d matrix holding a 3d image after projection
* @param matrix_3d: 3d matrix holding the original 3d image, without any transformation
*/
static void draw_3d_image(ekf_imu13states *ekf13, dspm::Mat &transformed_image, dspm::Mat &projected_image, dspm::Mat &matrix_3d)
{
static const float movement_treshold = 0.0001; // threshold to decide between Idle and Active state of the board
static float inactive_rotation = 0; // rotation angle (in degrees) for Idle state
static unsigned int inactivity_count = 0;
static const unsigned int inactivity_count_treshold = 75;
static unsigned int inactivity_check = 0; // activity of the board is being checked once in N calls of the function
static float prev_state_arr[3] = {0, 0, 0}; // holds the previous state of the Euler angles, to compare the diff
dspm::Mat T = dspm::Mat::eye(MATRIX_SIZE); // Transformation matrix
dspm::Mat R1 = ekf::quat2rotm(ekf13->X.data); // matrix(3x1) that holds x, y, z rotation data
dspm::Mat eul_angles = ekf::rotm2eul(R1);
// check if the board is active or not every N calls of the function
if (!(inactivity_check++ % 10)) {
dspm::Mat prev_state_mat(prev_state_arr, 3, 1);
dspm::Mat diff = eul_angles - prev_state_mat;
prev_state_mat = eul_angles;
float max_diff = fabs(diff(0, 0) * diff(1, 0) * diff(2, 0));
// wake-up the board if the current board movement crosses the threshold
if (board_inactive && (max_diff > movement_treshold)) {
board_inactive = false;
ESP_LOGI("Board status", "board put to active mode");
}
// if the board is awake, and the current movement of the board is lower than the threshold - the board is
// being moved with - run the inactivity_counter
// after some time (if the movement of the board has been lower than the threshold) put the board to idle mode
else if (!board_inactive && (max_diff < movement_treshold)) {
if (inactivity_count > inactivity_count_treshold) {
board_inactive = true;
inactivity_count = 0;
ESP_LOGI("Board status", "board put to idle mode");
update_perspective_matrix(perspective_matrix, 90);
}
inactivity_count++;
}
// if the board is awake and the current movement of the board is higher than the threshold clear the inactivity_counter
else if (!board_inactive && (max_diff >= movement_treshold)) {
inactivity_count = 0;
}
}
if (board_inactive) {
// board idle state - display a rotating cube
update_rotation_matrix(T, inactive_rotation += 3.0, 10.0, 10.0);
} else {
// board active state - 3D object follows movements of the board
eul_angles(2, 0) = -eul_angles(2, 0);
dspm::Mat R = ekf::eul2rotm(eul_angles.data);
// Enlarge rotation matrix from 3x3 to 4x4
// Copy rotation matrix R(3x3) to transformation matrix T_m(4x4)
for (int row = 0; row < R.rows; row++) {
for (int col = 0; col < R.cols; col++) {
T(row, col) = R(row, col);
}
}
}
// explanation for the matrix multiplication is for the 3D cube scenario, applies for all of the objects
// where matrix rows for the transformed image and the projected image are set according to the specific 3d object
// matrix mul cube_matirx(8x4) * transformation_matrix(4x4) = transformed_cube(8x4)
transformed_image = matrix_3d * T;
// matrix mul transformed_cube(8x4) * perspective_matrix(4x4) = projected_cube(8x4)
projected_image = transformed_image * perspective_matrix;
display_3d_image(projected_image);
}
/**
* @brief Kalman filter RTOS task (or ESP timer callback)
*
* Takes IMU sensors measurements to be processed by the Kalman filter
* Function is used as:
* RTOS task - during normal Kalman filter operation
* ESP Timer callback function - during Kalman filter calibration process
*
* @param arg: pointer to RTOS task arguments, 3d image structure in this case
*/
static void kalman_filter_task(void *arg)
{
mpu6050_acce_value_t acce_sample;
mpu6050_gyro_value_t gyro_sample;
mag3110_result_t mag_sample;
image_3d_matrix_kalman_t *kalman_filter_args = (image_3d_matrix_kalman_t *)arg;
ekf_imu13states *ekf13 = kalman_filter_args->ekf13;
dspm::Mat transformed_image(kalman_filter_args->matrix_len, MATRIX_SIZE); // 3D image matrix after transformation
dspm::Mat projected_image(kalman_filter_args->matrix_len, MATRIX_SIZE); // 3D image matrix after projection
dspm::Mat matrix_3d((float *)kalman_filter_args->matrix[0], kalman_filter_args->matrix_len, MATRIX_SIZE);
// Covariance matrix for Kalman filter, set specifically for this development board IMU sensors
float R_m[10] = {0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.0001, 0.000001, 0.000001, 0.000001, 0.000001};
update_perspective_matrix(perspective_matrix, 90);
while (1) {
// dt calculation
static float prev_time = 0;
const float current_time = dsp_get_cpu_cycle_count();
float dt = 0;
// Crystal count difference conversion to Dt time constant
if (current_time > prev_time) {
dt = current_time - prev_time;
dt = dt / 240000000.0;
}
prev_time = current_time;
// Get all the sensors values
mpu6050_get_acce(mpu6050_dev, &acce_sample);
mpu6050_get_gyro(mpu6050_dev, &gyro_sample);
mag3110_get_magnetic_induction(mag3110_dev, &mag_sample);
// Make arrays from the sensors values
float gyro_input_arr[3] = {gyro_sample.gyro_x, gyro_sample.gyro_y, gyro_sample.gyro_z};
float accel_input_arr[3] = {acce_sample.acce_x, acce_sample.acce_y, acce_sample.acce_z};
float mag_input_arr[3] = {(float)mag_sample.x, (float)mag_sample.y, (float)mag_sample.z};
// Accel and Mag data to Mat class
dspm::Mat gyro_input_mat(gyro_input_arr, 3, 1);
dspm::Mat accel_input_mat(accel_input_arr, 3, 1);
dspm::Mat mag_input_mat(mag_input_arr, 3, 1);
// Normalize vectors
dspm::Mat accel_norm = accel_input_mat / accel_input_mat.norm();
dspm::Mat magn_norm = mag_input_mat / mag_input_mat.norm();
gyro_input_mat *= DEG_TO_RAD;
ekf13->Process(gyro_input_mat.data, dt);
ekf13->UpdateRefMeasurementMagn(accel_norm.data, magn_norm.data, R_m);
if (kalman_filter_calibrated) {
// Use the function as RTOS task for the filter calculation
draw_3d_image(ekf13, transformed_image, projected_image, matrix_3d);
vTaskDelay(20 / portTICK_PERIOD_MS);
} else {
// Use the function as a callback for kalman_filter_calibration_timer
break;
}
}
}
/**
* @brief Kalman filter calibration procedure
*
* The Kalman filter must be calibrated before the very first run. The state of the Kalman filter is saved
* into NVS after the calibration.
* The calibration is run, only if no Kalman filter state is saved in the NVS. Which occurs after erasing
* the flash memory. Power cycling the board does not remove the Kalman filter state from the NVS.
*
* @param image: pointer to 3d image structure
*/
static void kalman_filter_calibration(image_3d_matrix_kalman_t *image)
{
ekf_imu13states *ekf13 = image->ekf13;
esp_err_t ret;
nvs_handle_t nvs_handle_kalman;
size_t state_vectors_size = 13 * 14;
float *state_vectors = (float *)malloc(state_vectors_size * sizeof(float));
ret = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &nvs_handle_kalman);
if (ret != ESP_OK) {
ESP_LOGE("NVS error", "(%s) opening NVS!\n", esp_err_to_name(ret));
assert(ESP_OK == ret);
}
// Read previously saved blob, if available
size_t required_size = 0; // value will default to 0, if not set yet in NVS
ret = nvs_get_blob(nvs_handle_kalman, "state_vectors", NULL, &required_size);
if (ret != ESP_OK && ret != ESP_ERR_NVS_NOT_FOUND) {
ESP_LOGE("NVS error", "(%s) reading data from NVS!\n", esp_err_to_name(ret));
assert(ESP_OK == ret);
}
if (required_size > 0) {
ESP_LOGI("Kalman filter demo", "Filter state vectors present in the NVS");
ESP_LOGI("Kalman filter demo", "Loading state vectors into the filter structure");
size_t state_vectors_size_addr = state_vectors_size * sizeof(float);
ret = nvs_get_blob(nvs_handle_kalman, "state_vectors", state_vectors, &state_vectors_size_addr);
if (ret != ESP_OK) {
ESP_LOGE("NVS error", "(%s) reading data from NVS!\n", esp_err_to_name(ret));
assert(ESP_OK == ret);
}
for (int i = 0; i < state_vectors_size; i++) {
if (i < state_vectors_size - 13) {
ekf13->P.data[i] = state_vectors[i];
} else {
ekf13->X.data[i - (state_vectors_size - 13)] = state_vectors[i];
}
}
ESP_LOGI("Kalman filter demo", "State vectors loaded from the NVS");
nvs_close(nvs_handle_kalman);
} else {
ESP_LOGI("Kalman filter demo", "Filter state vectors not present in the NVS");
const float kalman_timer_period_us = 100000;
// ESP timer for the Kalman filter calibration
const esp_timer_create_args_t kalman_calibration_timer_config = {
.callback = kalman_filter_task,
.arg = image,
.dispatch_method = ESP_TIMER_TASK,
.name = "kalman_filter_calibration_timer",
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0)
.skip_unhandled_events = true,
#endif
};
esp_timer_handle_t kalman_calibration_timer = NULL;
ret = esp_timer_create(&kalman_calibration_timer_config, &kalman_calibration_timer);
assert(ESP_OK == ret);
ssd1306_clear_screen(ssd1306_dev, 0x00);
ESP_LOGI("Kalman filter demo", "Starting Kalman filter calibration loop");
ssd1306_clear_screen(ssd1306_dev, 0x00);
ssd1306_draw_string(ssd1306_dev, 0, 16, (const uint8_t *)"Kalman filter", 16, 1);
ssd1306_draw_string(ssd1306_dev, 0, 32, (const uint8_t *)"calibration", 16, 1);
ssd1306_refresh_gram(ssd1306_dev);
ret = esp_timer_start_periodic(kalman_calibration_timer, kalman_timer_period_us);
assert(ESP_OK == ret);
vTaskDelay(100000 / portTICK_PERIOD_MS);
ret = esp_timer_stop(kalman_calibration_timer);
assert(ESP_OK == ret);
ret = esp_timer_delete(kalman_calibration_timer);
assert(ESP_OK == ret);
ESP_LOGI("Kalman filter demo", "Exiting Kalman filter calibration loop");
ssd1306_draw_string(ssd1306_dev, 0, 48, (const uint8_t *)"Done!", 16, 1);
ssd1306_refresh_gram(ssd1306_dev);
vTaskDelay(100 / portTICK_PERIOD_MS);
dspm::Mat estimated_error(&ekf13->X.data[4], 3, 1);
ESP_LOGI("Kalman filter demo", "Estimated gyroscope bias error [deg/sec]: %.6f\t%.6f\t%.6f",
estimated_error.data[0], estimated_error.data[1], estimated_error.data[2]);
for (int i = 0; i < state_vectors_size; i++) {
if (i < state_vectors_size - 13) {
state_vectors[i] = ekf13->P.data[i];
} else {
state_vectors[i] = ekf13->X.data[i - (state_vectors_size - 13)];
}
}
ret = nvs_set_blob(nvs_handle_kalman, "state_vectors", state_vectors, state_vectors_size * sizeof(float));
assert(ESP_OK == ret);
ret = nvs_commit(nvs_handle_kalman);
assert(ESP_OK == ret);
nvs_close(nvs_handle_kalman);
ESP_LOGI("Kalman filter demo", "State vectors saved to the NVS");
}
// Set the initial state of the X vector
ekf13->X(0, 0) = 1;
ekf13->X(0, 1) = 0;
ekf13->X(0, 2) = 0;
ekf13->X(0, 3) = 0;
free(state_vectors);
kalman_filter_calibrated = true;
}
/**
* @brief RTOS task to periodically save the filter state
*
* The Kalman filter state is periodically saved into the NVS, each 5 min. So a recent Kalman filter state
* could be loaded into the Kalman filter object after a power cycle.
*
* @param arg: pointer to RTOS task arguments, Kalman filter object in this case
*/
static void save_state_vectors_task(void *arg)
{
esp_err_t ret;
size_t state_vectors_size = 13 * 14;
nvs_handle_t nvs_handle_kalman;
ekf_imu13states *ekf13 = (ekf_imu13states *)arg;
vTaskDelay((60000 * 5) / portTICK_PERIOD_MS); // 5min
while (1) {
float *state_vectors = (float *)malloc(state_vectors_size * sizeof(float));
ret = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &nvs_handle_kalman);
if (ret != ESP_OK) {
ESP_LOGE("NVS error", "(%s) opening NVS!\n", esp_err_to_name(ret));
assert(ESP_OK == ret);
}
for (int i = 0; i < state_vectors_size; i++) {
if (i < state_vectors_size - 13) {
state_vectors[i] = ekf13->P.data[i];
} else {
state_vectors[i] = ekf13->X.data[i - (state_vectors_size - 13)];
}
}
ret = nvs_set_blob(nvs_handle_kalman, "state_vectors", state_vectors, state_vectors_size * sizeof(float));
if (ret != ESP_OK && ret != ESP_ERR_NVS_NOT_FOUND) {
ESP_LOGE("NVS error", "(%s) writing data to NVS!\n", esp_err_to_name(ret));
assert(ESP_OK == ret);
}
ret = nvs_commit(nvs_handle_kalman);
if (ret != ESP_OK && ret != ESP_ERR_NVS_NOT_FOUND) {
ESP_LOGE("NVS error", "(%s) commiting data to NVS!\n", esp_err_to_name(ret));
assert(ESP_OK == ret);
}
nvs_close(nvs_handle_kalman);
ESP_LOGI("Kalman filter demo", "State vectors saved to NVS");
free(state_vectors);
vTaskDelay((60000 * 5) / portTICK_PERIOD_MS); // Save the State vectors each 5 min
}
}
/**
* @brief ROTS task to read a pressure
*
* Pressure is measured periodically to better average out a stable value of pressure
*
* @param arg: pointer to RTOS task arguments, pointer to the pressure variable in this case
*/
static void get_pressure_task(void *arg)
{
int32_t real_p, real_t;
float *pressure_ptr = (float *)arg;
float pressure_global = *pressure_ptr;
int call_count = 0;
int call_count1 = 0;
float pressure_initial = pressure_global;
float last_pressure = pressure_global;
float baro_image = pressure_global;
bool changed = false;
while (1) {
if (ESP_OK == fbm320_get_data(fbm320_dev, FBM320_MEAS_PRESS_OSR_4096, &real_t, &real_p)) {
pressure_global = (0.999 * pressure_global) + (0.001 * ((float)real_p) / 1000.0);
call_count1++;
}
if (board_inactive) {
pressure_initial = pressure_global;
last_pressure = pressure_global;
baro_image = pressure_global;
} else {
call_count++;
if (fabs(pressure_global - last_pressure) > 0.0005) { // cahnge more than 0.5 Pa
last_pressure = pressure_global;
baro_image = (0.9 * baro_image) + (0.1 * last_pressure);
changed = true;
}
if ((!(call_count % 10)) && changed) {
float fov = 90 + (1000.0 * ((float)(pressure_initial - baro_image)));
update_perspective_matrix(perspective_matrix, fov);
changed = false;
}
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
/**
* @brief read the initial value of pressure
*/
float get_initial_pressure(void)
{
float pressure;
int32_t real_p, real_t;
int averagning_loop_count = 500;
ESP_LOGI("Barometer", "Averagining initial barometer pressure");
ssd1306_clear_screen(ssd1306_dev, 0x00);
ssd1306_draw_string(ssd1306_dev, 0, 16, (const uint8_t *)"Barometer", 16, 1);
ssd1306_draw_string(ssd1306_dev, 0, 32, (const uint8_t *)"averaging", 16, 1);
ssd1306_refresh_gram(ssd1306_dev);
// take the first pressure measurement
while (1) {
if (ESP_OK == fbm320_get_data(fbm320_dev, FBM320_MEAS_PRESS_OSR_4096, &real_t, &real_p)) {
pressure = ((float)real_p) / 1000.0; // pressure in kPa
break;
}
}
// average first N measurements
while (averagning_loop_count--) {
if (ESP_OK == fbm320_get_data(fbm320_dev, FBM320_MEAS_PRESS_OSR_4096, &real_t, &real_p)) {
pressure = (0.999 * pressure) + (0.001 * ((float)real_p) / 1000.0);
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
ESP_LOGI("Barometer", "Initial value set");
ssd1306_draw_string(ssd1306_dev, 0, 48, (const uint8_t *)"Done!", 16, 1);
ssd1306_refresh_gram(ssd1306_dev);
return (pressure);
}
void app_main(void)
{
image_3d_matrix_kalman_t image;
ekf_imu13states *ekf13 = new ekf_imu13states();
ekf13->Init();
// Init all board components
bsp_i2c_init();
app_ssd1306_init(); // display init
mpu6050_init(); // gyro, acc init
app_mag3110_init(); // magnetometer init
app_fbm320_init(); // barometer init
bsp_leds_init(); // LEDs init
init_nvs_flash_memory(); // Non-Volatile Storage
init_perspective_matrix(perspective_matrix);
init_3d_matrix_struct(&image, ekf13);
kalman_filter_calibration(&image);
// Use a barometer for measuring the altitude
if (USE_BAROMETER) {
float init_pressure = get_initial_pressure();
xTaskCreate(get_pressure_task, "get_pressure_task", 2048 * 4, &init_pressure, 4, NULL);
} else {
ESP_LOGI("Barometer", "disabled");
}
xTaskCreate(kalman_filter_task, "kalman_filter_task", 2048 * 4, &image, 5, NULL);
xTaskCreate(save_state_vectors_task, "save_state_vectors", 2048, ekf13, 6, NULL);
while (1) {
vTaskDelay(10000 / portTICK_PERIOD_MS);
}
}

View File

@@ -0,0 +1,3 @@
img_to_3d_matrix/converted_image/**
img_to_3d_matrix/example/*.c
img_to_3d_matrix/example/*.h

View File

@@ -0,0 +1,51 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "graphics_support.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define CUBE_POINTS 8
#define CUBE_EDGES 12
#define CUBE_SIDE (SSD1606_Y_CENTER / 2)
// X Y Z coordinates of the cube centered to (0, 0, 0)
const float cube_vectors_3d[CUBE_POINTS][MATRIX_SIZE] =
// X Y Z W
{ {-CUBE_SIDE, -CUBE_SIDE, -CUBE_SIDE, 1}, // -1, -1, -1
{-CUBE_SIDE, -CUBE_SIDE, CUBE_SIDE, 1}, // -1, -1, 1
{-CUBE_SIDE, CUBE_SIDE, -CUBE_SIDE, 1}, // -1, 1, -1
{-CUBE_SIDE, CUBE_SIDE, CUBE_SIDE, 1}, // -1, 1, 1
{ CUBE_SIDE, -CUBE_SIDE, -CUBE_SIDE, 1}, // 1, -1, -1
{ CUBE_SIDE, -CUBE_SIDE, CUBE_SIDE, 1}, // 1, -1, 1
{ CUBE_SIDE, CUBE_SIDE, -CUBE_SIDE, 1}, // 1, 1, -1
{ CUBE_SIDE, CUBE_SIDE, CUBE_SIDE, 1} // 1, 1, 1
};
// Dictionary for 3d cube edges displaying
// Cube edges cube_vectors_3d[3] <-> cube_vectors_3d[1]
// cube_vectors_3d[3] <-> cube_vectors_3d[7]
// cube_vectors_3d[5] <-> cube_vectors_3d[7]
// cube_vectors_3d[5] <-> cube_vectors_3d[1]....
const uint8_t cube_dict_line_begin[CUBE_EDGES] = {3, 3, 5, 5, 2, 2, 4, 4, 3, 7, 1, 5};
const uint8_t cube_dict_line_end[CUBE_EDGES] = {1, 7, 7, 1, 0, 6, 6, 0, 2, 6, 0, 4};
#ifdef CONFIG_3D_OBJECT_CUBE
#define OBJECT_3D_CUBE 1
#else
#define OBJECT_3D_CUBE 0
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,290 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_logo.h"
#ifdef CONFIG_3D_OBJECT_ESP_LOGO
const uint8_t image_bmp_array_esp_logo[512] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xc0, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x0c, 0x1f, 0xfc, 0x07, 0xfe, 0x00, 0x00,
0x00, 0x0c, 0x3f, 0xff, 0x03, 0xff, 0x00, 0x00, 0x00, 0x18, 0x7f, 0xff, 0xc0, 0xff, 0xc0, 0x00,
0x00, 0x38, 0x7f, 0xff, 0xf0, 0x7f, 0xe0, 0x00, 0x00, 0x70, 0x7f, 0xff, 0xf8, 0x3f, 0xe0, 0x00,
0x00, 0x60, 0x7f, 0xff, 0xfe, 0x0f, 0xf0, 0x00, 0x00, 0xe0, 0x01, 0xff, 0xff, 0x07, 0xf8, 0x00,
0x00, 0xc0, 0x00, 0x3f, 0xff, 0x83, 0xfc, 0x00, 0x01, 0xc0, 0x00, 0x07, 0xff, 0xe1, 0xfc, 0x00,
0x01, 0x81, 0xfc, 0x01, 0xff, 0xf0, 0xfe, 0x00, 0x01, 0x87, 0xff, 0xc0, 0x7f, 0xf8, 0xfe, 0x00,
0x03, 0x0f, 0xff, 0xf0, 0x3f, 0xf8, 0x7e, 0x00, 0x03, 0x1f, 0xff, 0xfc, 0x1f, 0xfc, 0x3f, 0x00,
0x03, 0x1f, 0xff, 0xff, 0x07, 0xfe, 0x1f, 0x00, 0x03, 0x3f, 0xff, 0xff, 0x83, 0xff, 0x1f, 0x00,
0x06, 0x3f, 0xff, 0xff, 0xc1, 0xff, 0x0f, 0x00, 0x06, 0x3f, 0xff, 0xff, 0xe0, 0xff, 0x8f, 0x80,
0x06, 0x7f, 0x83, 0xff, 0xf0, 0xff, 0xc7, 0x80, 0x06, 0x7f, 0x80, 0x7f, 0xf8, 0x7f, 0xc7, 0x80,
0x06, 0x7f, 0xc0, 0x1f, 0xfc, 0x3f, 0xe3, 0x80, 0x06, 0x3f, 0xfc, 0x0f, 0xfe, 0x3f, 0xe3, 0x80,
0x06, 0x3f, 0xff, 0x07, 0xff, 0x1f, 0xf1, 0x80, 0x06, 0x3f, 0xff, 0xc3, 0xff, 0x0f, 0xf0, 0x00,
0x06, 0x1f, 0xff, 0xe1, 0xff, 0x8f, 0xf0, 0x00, 0x07, 0x0f, 0xff, 0xf0, 0xff, 0x8f, 0xf8, 0x00,
0x03, 0x07, 0xff, 0xf8, 0x7f, 0xc7, 0xf8, 0x00, 0x03, 0x01, 0xff, 0xfc, 0x3f, 0xc7, 0xf8, 0x00,
0x03, 0x00, 0x3f, 0xfe, 0x3f, 0xc7, 0xf8, 0x00, 0x01, 0x80, 0x07, 0xfe, 0x1f, 0xe3, 0xfc, 0x00,
0x01, 0x80, 0x03, 0xff, 0x1f, 0xe3, 0xfc, 0x00, 0x01, 0xc0, 0x01, 0xff, 0x1f, 0xe3, 0xfc, 0x00,
0x00, 0xc0, 0x78, 0xff, 0x0f, 0xe3, 0xfc, 0x00, 0x00, 0xe0, 0xfc, 0x7f, 0x8f, 0xf1, 0xf8, 0x00,
0x00, 0x61, 0xfc, 0x7f, 0x8f, 0xf1, 0xf0, 0x00, 0x00, 0x71, 0xfc, 0x7f, 0x8f, 0xf1, 0xf0, 0x00,
0x00, 0x39, 0xfc, 0x7f, 0x8f, 0xf1, 0xe0, 0x00, 0x00, 0x19, 0xfc, 0x7f, 0x8f, 0xf0, 0x00, 0x00,
0x00, 0x1c, 0xf8, 0x7f, 0x8f, 0xf0, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x7f, 0x8f, 0xf0, 0x10, 0x00,
0x00, 0x07, 0x00, 0x7f, 0x8f, 0xf0, 0x38, 0x00, 0x00, 0x03, 0xc0, 0xff, 0x0f, 0xe0, 0x70, 0x00,
0x00, 0x01, 0xe0, 0x7f, 0x0f, 0xc0, 0xe0, 0x00, 0x00, 0x00, 0x78, 0x1f, 0x00, 0x03, 0xc0, 0x00,
0x00, 0x00, 0x3e, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x7e, 0x00, 0x00,
0x00, 0x00, 0x03, 0xfc, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const float image_3d_matrix_esp_logo[1427][4] = {
{-2.0, -25.0, 0, 1}, {-1.0, -25.0, 0, 1}, {0.0, -25.0, 0, 1}, {1.0, -25.0, 0, 1}, {2.0, -25.0, 0, 1}, {3.0, -25.0, 0, 1},
{4.0, -25.0, 0, 1}, {5.0, -25.0, 0, 1}, {6.0, -25.0, 0, 1}, {-2.0, -24.0, 0, 1}, {-1.0, -24.0, 0, 1}, {0.0, -24.0, 0, 1},
{1.0, -24.0, 0, 1}, {2.0, -24.0, 0, 1}, {3.0, -24.0, 0, 1}, {4.0, -24.0, 0, 1}, {5.0, -24.0, 0, 1}, {6.0, -24.0, 0, 1},
{7.0, -24.0, 0, 1}, {8.0, -24.0, 0, 1}, {9.0, -24.0, 0, 1}, {1.0, -23.0, 0, 1}, {2.0, -23.0, 0, 1}, {3.0, -23.0, 0, 1},
{4.0, -23.0, 0, 1}, {5.0, -23.0, 0, 1}, {6.0, -23.0, 0, 1}, {7.0, -23.0, 0, 1}, {8.0, -23.0, 0, 1}, {9.0, -23.0, 0, 1},
{10.0, -23.0, 0, 1}, {11.0, -23.0, 0, 1}, {-12.0, -22.0, 0, 1}, {-11.0, -22.0, 0, 1}, {-10.0, -22.0, 0, 1}, {-9.0, -22.0, 0, 1},
{-8.0, -22.0, 0, 1}, {-7.0, -22.0, 0, 1}, {3.0, -22.0, 0, 1}, {4.0, -22.0, 0, 1}, {5.0, -22.0, 0, 1}, {6.0, -22.0, 0, 1},
{7.0, -22.0, 0, 1}, {8.0, -22.0, 0, 1}, {9.0, -22.0, 0, 1}, {10.0, -22.0, 0, 1}, {11.0, -22.0, 0, 1}, {12.0, -22.0, 0, 1},
{13.0, -22.0, 0, 1}, {-20.0, -21.0, 0, 1}, {-19.0, -21.0, 0, 1}, {-13.0, -21.0, 0, 1}, {-12.0, -21.0, 0, 1}, {-11.0, -21.0, 0, 1},
{-10.0, -21.0, 0, 1}, {-9.0, -21.0, 0, 1}, {-8.0, -21.0, 0, 1}, {-7.0, -21.0, 0, 1}, {-6.0, -21.0, 0, 1}, {-5.0, -21.0, 0, 1},
{-4.0, -21.0, 0, 1}, {-3.0, -21.0, 0, 1}, {5.0, -21.0, 0, 1}, {6.0, -21.0, 0, 1}, {7.0, -21.0, 0, 1}, {8.0, -21.0, 0, 1},
{9.0, -21.0, 0, 1}, {10.0, -21.0, 0, 1}, {11.0, -21.0, 0, 1}, {12.0, -21.0, 0, 1}, {13.0, -21.0, 0, 1}, {14.0, -21.0, 0, 1},
{-20.0, -20.0, 0, 1}, {-19.0, -20.0, 0, 1}, {-14.0, -20.0, 0, 1}, {-13.0, -20.0, 0, 1}, {-12.0, -20.0, 0, 1}, {-11.0, -20.0, 0, 1},
{-10.0, -20.0, 0, 1}, {-9.0, -20.0, 0, 1}, {-8.0, -20.0, 0, 1}, {-7.0, -20.0, 0, 1}, {-6.0, -20.0, 0, 1}, {-5.0, -20.0, 0, 1},
{-4.0, -20.0, 0, 1}, {-3.0, -20.0, 0, 1}, {-2.0, -20.0, 0, 1}, {-1.0, -20.0, 0, 1}, {6.0, -20.0, 0, 1}, {7.0, -20.0, 0, 1},
{8.0, -20.0, 0, 1}, {9.0, -20.0, 0, 1}, {10.0, -20.0, 0, 1}, {11.0, -20.0, 0, 1}, {12.0, -20.0, 0, 1}, {13.0, -20.0, 0, 1},
{14.0, -20.0, 0, 1}, {15.0, -20.0, 0, 1}, {-21.0, -19.0, 0, 1}, {-20.0, -19.0, 0, 1}, {-15.0, -19.0, 0, 1}, {-14.0, -19.0, 0, 1},
{-13.0, -19.0, 0, 1}, {-12.0, -19.0, 0, 1}, {-11.0, -19.0, 0, 1}, {-10.0, -19.0, 0, 1}, {-9.0, -19.0, 0, 1}, {-8.0, -19.0, 0, 1},
{-7.0, -19.0, 0, 1}, {-6.0, -19.0, 0, 1}, {-5.0, -19.0, 0, 1}, {-4.0, -19.0, 0, 1}, {-3.0, -19.0, 0, 1}, {-2.0, -19.0, 0, 1},
{-1.0, -19.0, 0, 1}, {0.0, -19.0, 0, 1}, {1.0, -19.0, 0, 1}, {8.0, -19.0, 0, 1}, {9.0, -19.0, 0, 1}, {10.0, -19.0, 0, 1},
{11.0, -19.0, 0, 1}, {12.0, -19.0, 0, 1}, {13.0, -19.0, 0, 1}, {14.0, -19.0, 0, 1}, {15.0, -19.0, 0, 1}, {16.0, -19.0, 0, 1},
{17.0, -19.0, 0, 1}, {-22.0, -18.0, 0, 1}, {-21.0, -18.0, 0, 1}, {-20.0, -18.0, 0, 1}, {-15.0, -18.0, 0, 1}, {-14.0, -18.0, 0, 1},
{-13.0, -18.0, 0, 1}, {-12.0, -18.0, 0, 1}, {-11.0, -18.0, 0, 1}, {-10.0, -18.0, 0, 1}, {-9.0, -18.0, 0, 1}, {-8.0, -18.0, 0, 1},
{-7.0, -18.0, 0, 1}, {-6.0, -18.0, 0, 1}, {-5.0, -18.0, 0, 1}, {-4.0, -18.0, 0, 1}, {-3.0, -18.0, 0, 1}, {-2.0, -18.0, 0, 1},
{-1.0, -18.0, 0, 1}, {0.0, -18.0, 0, 1}, {1.0, -18.0, 0, 1}, {2.0, -18.0, 0, 1}, {3.0, -18.0, 0, 1}, {9.0, -18.0, 0, 1},
{10.0, -18.0, 0, 1}, {11.0, -18.0, 0, 1}, {12.0, -18.0, 0, 1}, {13.0, -18.0, 0, 1}, {14.0, -18.0, 0, 1}, {15.0, -18.0, 0, 1},
{16.0, -18.0, 0, 1}, {17.0, -18.0, 0, 1}, {18.0, -18.0, 0, 1}, {-23.0, -17.0, 0, 1}, {-22.0, -17.0, 0, 1}, {-21.0, -17.0, 0, 1},
{-15.0, -17.0, 0, 1}, {-14.0, -17.0, 0, 1}, {-13.0, -17.0, 0, 1}, {-12.0, -17.0, 0, 1}, {-11.0, -17.0, 0, 1}, {-10.0, -17.0, 0, 1},
{-9.0, -17.0, 0, 1}, {-8.0, -17.0, 0, 1}, {-7.0, -17.0, 0, 1}, {-6.0, -17.0, 0, 1}, {-5.0, -17.0, 0, 1}, {-4.0, -17.0, 0, 1},
{-3.0, -17.0, 0, 1}, {-2.0, -17.0, 0, 1}, {-1.0, -17.0, 0, 1}, {0.0, -17.0, 0, 1}, {1.0, -17.0, 0, 1}, {2.0, -17.0, 0, 1},
{3.0, -17.0, 0, 1}, {4.0, -17.0, 0, 1}, {10.0, -17.0, 0, 1}, {11.0, -17.0, 0, 1}, {12.0, -17.0, 0, 1}, {13.0, -17.0, 0, 1},
{14.0, -17.0, 0, 1}, {15.0, -17.0, 0, 1}, {16.0, -17.0, 0, 1}, {17.0, -17.0, 0, 1}, {18.0, -17.0, 0, 1}, {-23.0, -16.0, 0, 1},
{-22.0, -16.0, 0, 1}, {-15.0, -16.0, 0, 1}, {-14.0, -16.0, 0, 1}, {-13.0, -16.0, 0, 1}, {-12.0, -16.0, 0, 1}, {-11.0, -16.0, 0, 1},
{-10.0, -16.0, 0, 1}, {-9.0, -16.0, 0, 1}, {-8.0, -16.0, 0, 1}, {-7.0, -16.0, 0, 1}, {-6.0, -16.0, 0, 1}, {-5.0, -16.0, 0, 1},
{-4.0, -16.0, 0, 1}, {-3.0, -16.0, 0, 1}, {-2.0, -16.0, 0, 1}, {-1.0, -16.0, 0, 1}, {0.0, -16.0, 0, 1}, {1.0, -16.0, 0, 1},
{2.0, -16.0, 0, 1}, {3.0, -16.0, 0, 1}, {4.0, -16.0, 0, 1}, {5.0, -16.0, 0, 1}, {6.0, -16.0, 0, 1}, {12.0, -16.0, 0, 1},
{13.0, -16.0, 0, 1}, {14.0, -16.0, 0, 1}, {15.0, -16.0, 0, 1}, {16.0, -16.0, 0, 1}, {17.0, -16.0, 0, 1}, {18.0, -16.0, 0, 1},
{19.0, -16.0, 0, 1}, {-24.0, -15.0, 0, 1}, {-23.0, -15.0, 0, 1}, {-22.0, -15.0, 0, 1}, {-9.0, -15.0, 0, 1}, {-8.0, -15.0, 0, 1},
{-7.0, -15.0, 0, 1}, {-6.0, -15.0, 0, 1}, {-5.0, -15.0, 0, 1}, {-4.0, -15.0, 0, 1}, {-3.0, -15.0, 0, 1}, {-2.0, -15.0, 0, 1},
{-1.0, -15.0, 0, 1}, {0.0, -15.0, 0, 1}, {1.0, -15.0, 0, 1}, {2.0, -15.0, 0, 1}, {3.0, -15.0, 0, 1}, {4.0, -15.0, 0, 1},
{5.0, -15.0, 0, 1}, {6.0, -15.0, 0, 1}, {7.0, -15.0, 0, 1}, {13.0, -15.0, 0, 1}, {14.0, -15.0, 0, 1}, {15.0, -15.0, 0, 1},
{16.0, -15.0, 0, 1}, {17.0, -15.0, 0, 1}, {18.0, -15.0, 0, 1}, {19.0, -15.0, 0, 1}, {20.0, -15.0, 0, 1}, {-24.0, -14.0, 0, 1},
{-23.0, -14.0, 0, 1}, {-6.0, -14.0, 0, 1}, {-5.0, -14.0, 0, 1}, {-4.0, -14.0, 0, 1}, {-3.0, -14.0, 0, 1}, {-2.0, -14.0, 0, 1},
{-1.0, -14.0, 0, 1}, {0.0, -14.0, 0, 1}, {1.0, -14.0, 0, 1}, {2.0, -14.0, 0, 1}, {3.0, -14.0, 0, 1}, {4.0, -14.0, 0, 1},
{5.0, -14.0, 0, 1}, {6.0, -14.0, 0, 1}, {7.0, -14.0, 0, 1}, {8.0, -14.0, 0, 1}, {14.0, -14.0, 0, 1}, {15.0, -14.0, 0, 1},
{16.0, -14.0, 0, 1}, {17.0, -14.0, 0, 1}, {18.0, -14.0, 0, 1}, {19.0, -14.0, 0, 1}, {20.0, -14.0, 0, 1}, {21.0, -14.0, 0, 1},
{-25.0, -13.0, 0, 1}, {-24.0, -13.0, 0, 1}, {-23.0, -13.0, 0, 1}, {-3.0, -13.0, 0, 1}, {-2.0, -13.0, 0, 1}, {-1.0, -13.0, 0, 1},
{0.0, -13.0, 0, 1}, {1.0, -13.0, 0, 1}, {2.0, -13.0, 0, 1}, {3.0, -13.0, 0, 1}, {4.0, -13.0, 0, 1}, {5.0, -13.0, 0, 1},
{6.0, -13.0, 0, 1}, {7.0, -13.0, 0, 1}, {8.0, -13.0, 0, 1}, {9.0, -13.0, 0, 1}, {10.0, -13.0, 0, 1}, {15.0, -13.0, 0, 1},
{16.0, -13.0, 0, 1}, {17.0, -13.0, 0, 1}, {18.0, -13.0, 0, 1}, {19.0, -13.0, 0, 1}, {20.0, -13.0, 0, 1}, {21.0, -13.0, 0, 1},
{-25.0, -12.0, 0, 1}, {-24.0, -12.0, 0, 1}, {-17.0, -12.0, 0, 1}, {-16.0, -12.0, 0, 1}, {-15.0, -12.0, 0, 1}, {-14.0, -12.0, 0, 1},
{-13.0, -12.0, 0, 1}, {-12.0, -12.0, 0, 1}, {-11.0, -12.0, 0, 1}, {-1.0, -12.0, 0, 1}, {0.0, -12.0, 0, 1}, {1.0, -12.0, 0, 1},
{2.0, -12.0, 0, 1}, {3.0, -12.0, 0, 1}, {4.0, -12.0, 0, 1}, {5.0, -12.0, 0, 1}, {6.0, -12.0, 0, 1}, {7.0, -12.0, 0, 1},
{8.0, -12.0, 0, 1}, {9.0, -12.0, 0, 1}, {10.0, -12.0, 0, 1}, {11.0, -12.0, 0, 1}, {16.0, -12.0, 0, 1}, {17.0, -12.0, 0, 1},
{18.0, -12.0, 0, 1}, {19.0, -12.0, 0, 1}, {20.0, -12.0, 0, 1}, {21.0, -12.0, 0, 1}, {22.0, -12.0, 0, 1}, {-25.0, -11.0, 0, 1},
{-24.0, -11.0, 0, 1}, {-19.0, -11.0, 0, 1}, {-18.0, -11.0, 0, 1}, {-17.0, -11.0, 0, 1}, {-16.0, -11.0, 0, 1}, {-15.0, -11.0, 0, 1},
{-14.0, -11.0, 0, 1}, {-13.0, -11.0, 0, 1}, {-12.0, -11.0, 0, 1}, {-11.0, -11.0, 0, 1}, {-10.0, -11.0, 0, 1}, {-9.0, -11.0, 0, 1},
{-8.0, -11.0, 0, 1}, {-7.0, -11.0, 0, 1}, {1.0, -11.0, 0, 1}, {2.0, -11.0, 0, 1}, {3.0, -11.0, 0, 1}, {4.0, -11.0, 0, 1},
{5.0, -11.0, 0, 1}, {6.0, -11.0, 0, 1}, {7.0, -11.0, 0, 1}, {8.0, -11.0, 0, 1}, {9.0, -11.0, 0, 1}, {10.0, -11.0, 0, 1},
{11.0, -11.0, 0, 1}, {12.0, -11.0, 0, 1}, {16.0, -11.0, 0, 1}, {17.0, -11.0, 0, 1}, {18.0, -11.0, 0, 1}, {19.0, -11.0, 0, 1},
{20.0, -11.0, 0, 1}, {21.0, -11.0, 0, 1}, {22.0, -11.0, 0, 1}, {-26.0, -10.0, 0, 1}, {-25.0, -10.0, 0, 1}, {-20.0, -10.0, 0, 1},
{-19.0, -10.0, 0, 1}, {-18.0, -10.0, 0, 1}, {-17.0, -10.0, 0, 1}, {-16.0, -10.0, 0, 1}, {-15.0, -10.0, 0, 1}, {-14.0, -10.0, 0, 1},
{-13.0, -10.0, 0, 1}, {-12.0, -10.0, 0, 1}, {-11.0, -10.0, 0, 1}, {-10.0, -10.0, 0, 1}, {-9.0, -10.0, 0, 1}, {-8.0, -10.0, 0, 1},
{-7.0, -10.0, 0, 1}, {-6.0, -10.0, 0, 1}, {-5.0, -10.0, 0, 1}, {2.0, -10.0, 0, 1}, {3.0, -10.0, 0, 1}, {4.0, -10.0, 0, 1},
{5.0, -10.0, 0, 1}, {6.0, -10.0, 0, 1}, {7.0, -10.0, 0, 1}, {8.0, -10.0, 0, 1}, {9.0, -10.0, 0, 1}, {10.0, -10.0, 0, 1},
{11.0, -10.0, 0, 1}, {12.0, -10.0, 0, 1}, {17.0, -10.0, 0, 1}, {18.0, -10.0, 0, 1}, {19.0, -10.0, 0, 1}, {20.0, -10.0, 0, 1},
{21.0, -10.0, 0, 1}, {22.0, -10.0, 0, 1}, {-26.0, -9.0, 0, 1}, {-25.0, -9.0, 0, 1}, {-21.0, -9.0, 0, 1}, {-20.0, -9.0, 0, 1},
{-19.0, -9.0, 0, 1}, {-18.0, -9.0, 0, 1}, {-17.0, -9.0, 0, 1}, {-16.0, -9.0, 0, 1}, {-15.0, -9.0, 0, 1}, {-14.0, -9.0, 0, 1},
{-13.0, -9.0, 0, 1}, {-12.0, -9.0, 0, 1}, {-11.0, -9.0, 0, 1}, {-10.0, -9.0, 0, 1}, {-9.0, -9.0, 0, 1}, {-8.0, -9.0, 0, 1},
{-7.0, -9.0, 0, 1}, {-6.0, -9.0, 0, 1}, {-5.0, -9.0, 0, 1}, {-4.0, -9.0, 0, 1}, {-3.0, -9.0, 0, 1}, {3.0, -9.0, 0, 1},
{4.0, -9.0, 0, 1}, {5.0, -9.0, 0, 1}, {6.0, -9.0, 0, 1}, {7.0, -9.0, 0, 1}, {8.0, -9.0, 0, 1}, {9.0, -9.0, 0, 1},
{10.0, -9.0, 0, 1}, {11.0, -9.0, 0, 1}, {12.0, -9.0, 0, 1}, {13.0, -9.0, 0, 1}, {18.0, -9.0, 0, 1}, {19.0, -9.0, 0, 1},
{20.0, -9.0, 0, 1}, {21.0, -9.0, 0, 1}, {22.0, -9.0, 0, 1}, {23.0, -9.0, 0, 1}, {-26.0, -8.0, 0, 1}, {-25.0, -8.0, 0, 1},
{-21.0, -8.0, 0, 1}, {-20.0, -8.0, 0, 1}, {-19.0, -8.0, 0, 1}, {-18.0, -8.0, 0, 1}, {-17.0, -8.0, 0, 1}, {-16.0, -8.0, 0, 1},
{-15.0, -8.0, 0, 1}, {-14.0, -8.0, 0, 1}, {-13.0, -8.0, 0, 1}, {-12.0, -8.0, 0, 1}, {-11.0, -8.0, 0, 1}, {-10.0, -8.0, 0, 1},
{-9.0, -8.0, 0, 1}, {-8.0, -8.0, 0, 1}, {-7.0, -8.0, 0, 1}, {-6.0, -8.0, 0, 1}, {-5.0, -8.0, 0, 1}, {-4.0, -8.0, 0, 1},
{-3.0, -8.0, 0, 1}, {-2.0, -8.0, 0, 1}, {-1.0, -8.0, 0, 1}, {5.0, -8.0, 0, 1}, {6.0, -8.0, 0, 1}, {7.0, -8.0, 0, 1},
{8.0, -8.0, 0, 1}, {9.0, -8.0, 0, 1}, {10.0, -8.0, 0, 1}, {11.0, -8.0, 0, 1}, {12.0, -8.0, 0, 1}, {13.0, -8.0, 0, 1},
{14.0, -8.0, 0, 1}, {19.0, -8.0, 0, 1}, {20.0, -8.0, 0, 1}, {21.0, -8.0, 0, 1}, {22.0, -8.0, 0, 1}, {23.0, -8.0, 0, 1},
{-26.0, -7.0, 0, 1}, {-25.0, -7.0, 0, 1}, {-22.0, -7.0, 0, 1}, {-21.0, -7.0, 0, 1}, {-20.0, -7.0, 0, 1}, {-19.0, -7.0, 0, 1},
{-18.0, -7.0, 0, 1}, {-17.0, -7.0, 0, 1}, {-16.0, -7.0, 0, 1}, {-15.0, -7.0, 0, 1}, {-14.0, -7.0, 0, 1}, {-13.0, -7.0, 0, 1},
{-12.0, -7.0, 0, 1}, {-11.0, -7.0, 0, 1}, {-10.0, -7.0, 0, 1}, {-9.0, -7.0, 0, 1}, {-8.0, -7.0, 0, 1}, {-7.0, -7.0, 0, 1},
{-6.0, -7.0, 0, 1}, {-5.0, -7.0, 0, 1}, {-4.0, -7.0, 0, 1}, {-3.0, -7.0, 0, 1}, {-2.0, -7.0, 0, 1}, {-1.0, -7.0, 0, 1},
{0.0, -7.0, 0, 1}, {6.0, -7.0, 0, 1}, {7.0, -7.0, 0, 1}, {8.0, -7.0, 0, 1}, {9.0, -7.0, 0, 1}, {10.0, -7.0, 0, 1},
{11.0, -7.0, 0, 1}, {12.0, -7.0, 0, 1}, {13.0, -7.0, 0, 1}, {14.0, -7.0, 0, 1}, {15.0, -7.0, 0, 1}, {19.0, -7.0, 0, 1},
{20.0, -7.0, 0, 1}, {21.0, -7.0, 0, 1}, {22.0, -7.0, 0, 1}, {23.0, -7.0, 0, 1}, {-27.0, -6.0, 0, 1}, {-26.0, -6.0, 0, 1},
{-22.0, -6.0, 0, 1}, {-21.0, -6.0, 0, 1}, {-20.0, -6.0, 0, 1}, {-19.0, -6.0, 0, 1}, {-18.0, -6.0, 0, 1}, {-17.0, -6.0, 0, 1},
{-16.0, -6.0, 0, 1}, {-15.0, -6.0, 0, 1}, {-14.0, -6.0, 0, 1}, {-13.0, -6.0, 0, 1}, {-12.0, -6.0, 0, 1}, {-11.0, -6.0, 0, 1},
{-10.0, -6.0, 0, 1}, {-9.0, -6.0, 0, 1}, {-8.0, -6.0, 0, 1}, {-7.0, -6.0, 0, 1}, {-6.0, -6.0, 0, 1}, {-5.0, -6.0, 0, 1},
{-4.0, -6.0, 0, 1}, {-3.0, -6.0, 0, 1}, {-2.0, -6.0, 0, 1}, {-1.0, -6.0, 0, 1}, {0.0, -6.0, 0, 1}, {1.0, -6.0, 0, 1},
{7.0, -6.0, 0, 1}, {8.0, -6.0, 0, 1}, {9.0, -6.0, 0, 1}, {10.0, -6.0, 0, 1}, {11.0, -6.0, 0, 1}, {12.0, -6.0, 0, 1},
{13.0, -6.0, 0, 1}, {14.0, -6.0, 0, 1}, {15.0, -6.0, 0, 1}, {20.0, -6.0, 0, 1}, {21.0, -6.0, 0, 1}, {22.0, -6.0, 0, 1},
{23.0, -6.0, 0, 1}, {-27.0, -5.0, 0, 1}, {-26.0, -5.0, 0, 1}, {-22.0, -5.0, 0, 1}, {-21.0, -5.0, 0, 1}, {-20.0, -5.0, 0, 1},
{-19.0, -5.0, 0, 1}, {-18.0, -5.0, 0, 1}, {-17.0, -5.0, 0, 1}, {-16.0, -5.0, 0, 1}, {-15.0, -5.0, 0, 1}, {-14.0, -5.0, 0, 1},
{-13.0, -5.0, 0, 1}, {-12.0, -5.0, 0, 1}, {-11.0, -5.0, 0, 1}, {-10.0, -5.0, 0, 1}, {-9.0, -5.0, 0, 1}, {-8.0, -5.0, 0, 1},
{-7.0, -5.0, 0, 1}, {-6.0, -5.0, 0, 1}, {-5.0, -5.0, 0, 1}, {-4.0, -5.0, 0, 1}, {-3.0, -5.0, 0, 1}, {-2.0, -5.0, 0, 1},
{-1.0, -5.0, 0, 1}, {0.0, -5.0, 0, 1}, {1.0, -5.0, 0, 1}, {2.0, -5.0, 0, 1}, {8.0, -5.0, 0, 1}, {9.0, -5.0, 0, 1},
{10.0, -5.0, 0, 1}, {11.0, -5.0, 0, 1}, {12.0, -5.0, 0, 1}, {13.0, -5.0, 0, 1}, {14.0, -5.0, 0, 1}, {15.0, -5.0, 0, 1},
{16.0, -5.0, 0, 1}, {20.0, -5.0, 0, 1}, {21.0, -5.0, 0, 1}, {22.0, -5.0, 0, 1}, {23.0, -5.0, 0, 1}, {24.0, -5.0, 0, 1},
{-27.0, -4.0, 0, 1}, {-26.0, -4.0, 0, 1}, {-23.0, -4.0, 0, 1}, {-22.0, -4.0, 0, 1}, {-21.0, -4.0, 0, 1}, {-20.0, -4.0, 0, 1},
{-19.0, -4.0, 0, 1}, {-18.0, -4.0, 0, 1}, {-17.0, -4.0, 0, 1}, {-16.0, -4.0, 0, 1}, {-10.0, -4.0, 0, 1}, {-9.0, -4.0, 0, 1},
{-8.0, -4.0, 0, 1}, {-7.0, -4.0, 0, 1}, {-6.0, -4.0, 0, 1}, {-5.0, -4.0, 0, 1}, {-4.0, -4.0, 0, 1}, {-3.0, -4.0, 0, 1},
{-2.0, -4.0, 0, 1}, {-1.0, -4.0, 0, 1}, {0.0, -4.0, 0, 1}, {1.0, -4.0, 0, 1}, {2.0, -4.0, 0, 1}, {3.0, -4.0, 0, 1},
{8.0, -4.0, 0, 1}, {9.0, -4.0, 0, 1}, {10.0, -4.0, 0, 1}, {11.0, -4.0, 0, 1}, {12.0, -4.0, 0, 1}, {13.0, -4.0, 0, 1},
{14.0, -4.0, 0, 1}, {15.0, -4.0, 0, 1}, {16.0, -4.0, 0, 1}, {17.0, -4.0, 0, 1}, {21.0, -4.0, 0, 1}, {22.0, -4.0, 0, 1},
{23.0, -4.0, 0, 1}, {24.0, -4.0, 0, 1}, {-27.0, -3.0, 0, 1}, {-26.0, -3.0, 0, 1}, {-23.0, -3.0, 0, 1}, {-22.0, -3.0, 0, 1},
{-21.0, -3.0, 0, 1}, {-20.0, -3.0, 0, 1}, {-19.0, -3.0, 0, 1}, {-18.0, -3.0, 0, 1}, {-17.0, -3.0, 0, 1}, {-16.0, -3.0, 0, 1},
{-7.0, -3.0, 0, 1}, {-6.0, -3.0, 0, 1}, {-5.0, -3.0, 0, 1}, {-4.0, -3.0, 0, 1}, {-3.0, -3.0, 0, 1}, {-2.0, -3.0, 0, 1},
{-1.0, -3.0, 0, 1}, {0.0, -3.0, 0, 1}, {1.0, -3.0, 0, 1}, {2.0, -3.0, 0, 1}, {3.0, -3.0, 0, 1}, {4.0, -3.0, 0, 1},
{9.0, -3.0, 0, 1}, {10.0, -3.0, 0, 1}, {11.0, -3.0, 0, 1}, {12.0, -3.0, 0, 1}, {13.0, -3.0, 0, 1}, {14.0, -3.0, 0, 1},
{15.0, -3.0, 0, 1}, {16.0, -3.0, 0, 1}, {17.0, -3.0, 0, 1}, {21.0, -3.0, 0, 1}, {22.0, -3.0, 0, 1}, {23.0, -3.0, 0, 1},
{24.0, -3.0, 0, 1}, {-27.0, -2.0, 0, 1}, {-26.0, -2.0, 0, 1}, {-23.0, -2.0, 0, 1}, {-22.0, -2.0, 0, 1}, {-21.0, -2.0, 0, 1},
{-20.0, -2.0, 0, 1}, {-19.0, -2.0, 0, 1}, {-18.0, -2.0, 0, 1}, {-17.0, -2.0, 0, 1}, {-16.0, -2.0, 0, 1}, {-15.0, -2.0, 0, 1},
{-5.0, -2.0, 0, 1}, {-4.0, -2.0, 0, 1}, {-3.0, -2.0, 0, 1}, {-2.0, -2.0, 0, 1}, {-1.0, -2.0, 0, 1}, {0.0, -2.0, 0, 1},
{1.0, -2.0, 0, 1}, {2.0, -2.0, 0, 1}, {3.0, -2.0, 0, 1}, {4.0, -2.0, 0, 1}, {5.0, -2.0, 0, 1}, {10.0, -2.0, 0, 1},
{11.0, -2.0, 0, 1}, {12.0, -2.0, 0, 1}, {13.0, -2.0, 0, 1}, {14.0, -2.0, 0, 1}, {15.0, -2.0, 0, 1}, {16.0, -2.0, 0, 1},
{17.0, -2.0, 0, 1}, {18.0, -2.0, 0, 1}, {22.0, -2.0, 0, 1}, {23.0, -2.0, 0, 1}, {24.0, -2.0, 0, 1}, {-27.0, -1.0, 0, 1},
{-26.0, -1.0, 0, 1}, {-22.0, -1.0, 0, 1}, {-21.0, -1.0, 0, 1}, {-20.0, -1.0, 0, 1}, {-19.0, -1.0, 0, 1}, {-18.0, -1.0, 0, 1},
{-17.0, -1.0, 0, 1}, {-16.0, -1.0, 0, 1}, {-15.0, -1.0, 0, 1}, {-14.0, -1.0, 0, 1}, {-13.0, -1.0, 0, 1}, {-12.0, -1.0, 0, 1},
{-11.0, -1.0, 0, 1}, {-4.0, -1.0, 0, 1}, {-3.0, -1.0, 0, 1}, {-2.0, -1.0, 0, 1}, {-1.0, -1.0, 0, 1}, {0.0, -1.0, 0, 1},
{1.0, -1.0, 0, 1}, {2.0, -1.0, 0, 1}, {3.0, -1.0, 0, 1}, {4.0, -1.0, 0, 1}, {5.0, -1.0, 0, 1}, {6.0, -1.0, 0, 1},
{10.0, -1.0, 0, 1}, {11.0, -1.0, 0, 1}, {12.0, -1.0, 0, 1}, {13.0, -1.0, 0, 1}, {14.0, -1.0, 0, 1}, {15.0, -1.0, 0, 1},
{16.0, -1.0, 0, 1}, {17.0, -1.0, 0, 1}, {18.0, -1.0, 0, 1}, {22.0, -1.0, 0, 1}, {23.0, -1.0, 0, 1}, {24.0, -1.0, 0, 1},
{-27.0, 0.0, 0, 1}, {-26.0, 0.0, 0, 1}, {-22.0, 0.0, 0, 1}, {-21.0, 0.0, 0, 1}, {-20.0, 0.0, 0, 1}, {-19.0, 0.0, 0, 1},
{-18.0, 0.0, 0, 1}, {-17.0, 0.0, 0, 1}, {-16.0, 0.0, 0, 1}, {-15.0, 0.0, 0, 1}, {-14.0, 0.0, 0, 1}, {-13.0, 0.0, 0, 1},
{-12.0, 0.0, 0, 1}, {-11.0, 0.0, 0, 1}, {-10.0, 0.0, 0, 1}, {-9.0, 0.0, 0, 1}, {-3.0, 0.0, 0, 1}, {-2.0, 0.0, 0, 1},
{-1.0, 0.0, 0, 1}, {0.0, 0.0, 0, 1}, {1.0, 0.0, 0, 1}, {2.0, 0.0, 0, 1}, {3.0, 0.0, 0, 1}, {4.0, 0.0, 0, 1},
{5.0, 0.0, 0, 1}, {6.0, 0.0, 0, 1}, {7.0, 0.0, 0, 1}, {11.0, 0.0, 0, 1}, {12.0, 0.0, 0, 1}, {13.0, 0.0, 0, 1},
{14.0, 0.0, 0, 1}, {15.0, 0.0, 0, 1}, {16.0, 0.0, 0, 1}, {17.0, 0.0, 0, 1}, {18.0, 0.0, 0, 1}, {19.0, 0.0, 0, 1},
{23.0, 0.0, 0, 1}, {24.0, 0.0, 0, 1}, {-27.0, 1.0, 0, 1}, {-26.0, 1.0, 0, 1}, {-22.0, 1.0, 0, 1}, {-21.0, 1.0, 0, 1},
{-20.0, 1.0, 0, 1}, {-19.0, 1.0, 0, 1}, {-18.0, 1.0, 0, 1}, {-17.0, 1.0, 0, 1}, {-16.0, 1.0, 0, 1}, {-15.0, 1.0, 0, 1},
{-14.0, 1.0, 0, 1}, {-13.0, 1.0, 0, 1}, {-12.0, 1.0, 0, 1}, {-11.0, 1.0, 0, 1}, {-10.0, 1.0, 0, 1}, {-9.0, 1.0, 0, 1},
{-8.0, 1.0, 0, 1}, {-7.0, 1.0, 0, 1}, {-2.0, 1.0, 0, 1}, {-1.0, 1.0, 0, 1}, {0.0, 1.0, 0, 1}, {1.0, 1.0, 0, 1},
{2.0, 1.0, 0, 1}, {3.0, 1.0, 0, 1}, {4.0, 1.0, 0, 1}, {5.0, 1.0, 0, 1}, {6.0, 1.0, 0, 1}, {7.0, 1.0, 0, 1},
{12.0, 1.0, 0, 1}, {13.0, 1.0, 0, 1}, {14.0, 1.0, 0, 1}, {15.0, 1.0, 0, 1}, {16.0, 1.0, 0, 1}, {17.0, 1.0, 0, 1},
{18.0, 1.0, 0, 1}, {19.0, 1.0, 0, 1}, {-27.0, 2.0, 0, 1}, {-26.0, 2.0, 0, 1}, {-21.0, 2.0, 0, 1}, {-20.0, 2.0, 0, 1},
{-19.0, 2.0, 0, 1}, {-18.0, 2.0, 0, 1}, {-17.0, 2.0, 0, 1}, {-16.0, 2.0, 0, 1}, {-15.0, 2.0, 0, 1}, {-14.0, 2.0, 0, 1},
{-13.0, 2.0, 0, 1}, {-12.0, 2.0, 0, 1}, {-11.0, 2.0, 0, 1}, {-10.0, 2.0, 0, 1}, {-9.0, 2.0, 0, 1}, {-8.0, 2.0, 0, 1},
{-7.0, 2.0, 0, 1}, {-6.0, 2.0, 0, 1}, {-1.0, 2.0, 0, 1}, {0.0, 2.0, 0, 1}, {1.0, 2.0, 0, 1}, {2.0, 2.0, 0, 1},
{3.0, 2.0, 0, 1}, {4.0, 2.0, 0, 1}, {5.0, 2.0, 0, 1}, {6.0, 2.0, 0, 1}, {7.0, 2.0, 0, 1}, {8.0, 2.0, 0, 1},
{12.0, 2.0, 0, 1}, {13.0, 2.0, 0, 1}, {14.0, 2.0, 0, 1}, {15.0, 2.0, 0, 1}, {16.0, 2.0, 0, 1}, {17.0, 2.0, 0, 1},
{18.0, 2.0, 0, 1}, {19.0, 2.0, 0, 1}, {-27.0, 3.0, 0, 1}, {-26.0, 3.0, 0, 1}, {-25.0, 3.0, 0, 1}, {-20.0, 3.0, 0, 1},
{-19.0, 3.0, 0, 1}, {-18.0, 3.0, 0, 1}, {-17.0, 3.0, 0, 1}, {-16.0, 3.0, 0, 1}, {-15.0, 3.0, 0, 1}, {-14.0, 3.0, 0, 1},
{-13.0, 3.0, 0, 1}, {-12.0, 3.0, 0, 1}, {-11.0, 3.0, 0, 1}, {-10.0, 3.0, 0, 1}, {-9.0, 3.0, 0, 1}, {-8.0, 3.0, 0, 1},
{-7.0, 3.0, 0, 1}, {-6.0, 3.0, 0, 1}, {-5.0, 3.0, 0, 1}, {0.0, 3.0, 0, 1}, {1.0, 3.0, 0, 1}, {2.0, 3.0, 0, 1},
{3.0, 3.0, 0, 1}, {4.0, 3.0, 0, 1}, {5.0, 3.0, 0, 1}, {6.0, 3.0, 0, 1}, {7.0, 3.0, 0, 1}, {8.0, 3.0, 0, 1},
{12.0, 3.0, 0, 1}, {13.0, 3.0, 0, 1}, {14.0, 3.0, 0, 1}, {15.0, 3.0, 0, 1}, {16.0, 3.0, 0, 1}, {17.0, 3.0, 0, 1},
{18.0, 3.0, 0, 1}, {19.0, 3.0, 0, 1}, {20.0, 3.0, 0, 1}, {-26.0, 4.0, 0, 1}, {-25.0, 4.0, 0, 1}, {-19.0, 4.0, 0, 1},
{-18.0, 4.0, 0, 1}, {-17.0, 4.0, 0, 1}, {-16.0, 4.0, 0, 1}, {-15.0, 4.0, 0, 1}, {-14.0, 4.0, 0, 1}, {-13.0, 4.0, 0, 1},
{-12.0, 4.0, 0, 1}, {-11.0, 4.0, 0, 1}, {-10.0, 4.0, 0, 1}, {-9.0, 4.0, 0, 1}, {-8.0, 4.0, 0, 1}, {-7.0, 4.0, 0, 1},
{-6.0, 4.0, 0, 1}, {-5.0, 4.0, 0, 1}, {-4.0, 4.0, 0, 1}, {1.0, 4.0, 0, 1}, {2.0, 4.0, 0, 1}, {3.0, 4.0, 0, 1},
{4.0, 4.0, 0, 1}, {5.0, 4.0, 0, 1}, {6.0, 4.0, 0, 1}, {7.0, 4.0, 0, 1}, {8.0, 4.0, 0, 1}, {9.0, 4.0, 0, 1},
{13.0, 4.0, 0, 1}, {14.0, 4.0, 0, 1}, {15.0, 4.0, 0, 1}, {16.0, 4.0, 0, 1}, {17.0, 4.0, 0, 1}, {18.0, 4.0, 0, 1},
{19.0, 4.0, 0, 1}, {20.0, 4.0, 0, 1}, {-26.0, 5.0, 0, 1}, {-25.0, 5.0, 0, 1}, {-17.0, 5.0, 0, 1}, {-16.0, 5.0, 0, 1},
{-15.0, 5.0, 0, 1}, {-14.0, 5.0, 0, 1}, {-13.0, 5.0, 0, 1}, {-12.0, 5.0, 0, 1}, {-11.0, 5.0, 0, 1}, {-10.0, 5.0, 0, 1},
{-9.0, 5.0, 0, 1}, {-8.0, 5.0, 0, 1}, {-7.0, 5.0, 0, 1}, {-6.0, 5.0, 0, 1}, {-5.0, 5.0, 0, 1}, {-4.0, 5.0, 0, 1},
{-3.0, 5.0, 0, 1}, {2.0, 5.0, 0, 1}, {3.0, 5.0, 0, 1}, {4.0, 5.0, 0, 1}, {5.0, 5.0, 0, 1}, {6.0, 5.0, 0, 1},
{7.0, 5.0, 0, 1}, {8.0, 5.0, 0, 1}, {9.0, 5.0, 0, 1}, {13.0, 5.0, 0, 1}, {14.0, 5.0, 0, 1}, {15.0, 5.0, 0, 1},
{16.0, 5.0, 0, 1}, {17.0, 5.0, 0, 1}, {18.0, 5.0, 0, 1}, {19.0, 5.0, 0, 1}, {20.0, 5.0, 0, 1}, {-26.0, 6.0, 0, 1},
{-25.0, 6.0, 0, 1}, {-14.0, 6.0, 0, 1}, {-13.0, 6.0, 0, 1}, {-12.0, 6.0, 0, 1}, {-11.0, 6.0, 0, 1}, {-10.0, 6.0, 0, 1},
{-9.0, 6.0, 0, 1}, {-8.0, 6.0, 0, 1}, {-7.0, 6.0, 0, 1}, {-6.0, 6.0, 0, 1}, {-5.0, 6.0, 0, 1}, {-4.0, 6.0, 0, 1},
{-3.0, 6.0, 0, 1}, {-2.0, 6.0, 0, 1}, {2.0, 6.0, 0, 1}, {3.0, 6.0, 0, 1}, {4.0, 6.0, 0, 1}, {5.0, 6.0, 0, 1},
{6.0, 6.0, 0, 1}, {7.0, 6.0, 0, 1}, {8.0, 6.0, 0, 1}, {9.0, 6.0, 0, 1}, {13.0, 6.0, 0, 1}, {14.0, 6.0, 0, 1},
{15.0, 6.0, 0, 1}, {16.0, 6.0, 0, 1}, {17.0, 6.0, 0, 1}, {18.0, 6.0, 0, 1}, {19.0, 6.0, 0, 1}, {20.0, 6.0, 0, 1},
{-25.0, 7.0, 0, 1}, {-24.0, 7.0, 0, 1}, {-11.0, 7.0, 0, 1}, {-10.0, 7.0, 0, 1}, {-9.0, 7.0, 0, 1}, {-8.0, 7.0, 0, 1},
{-7.0, 7.0, 0, 1}, {-6.0, 7.0, 0, 1}, {-5.0, 7.0, 0, 1}, {-4.0, 7.0, 0, 1}, {-3.0, 7.0, 0, 1}, {-2.0, 7.0, 0, 1},
{3.0, 7.0, 0, 1}, {4.0, 7.0, 0, 1}, {5.0, 7.0, 0, 1}, {6.0, 7.0, 0, 1}, {7.0, 7.0, 0, 1}, {8.0, 7.0, 0, 1},
{9.0, 7.0, 0, 1}, {10.0, 7.0, 0, 1}, {14.0, 7.0, 0, 1}, {15.0, 7.0, 0, 1}, {16.0, 7.0, 0, 1}, {17.0, 7.0, 0, 1},
{18.0, 7.0, 0, 1}, {19.0, 7.0, 0, 1}, {20.0, 7.0, 0, 1}, {21.0, 7.0, 0, 1}, {-25.0, 8.0, 0, 1}, {-24.0, 8.0, 0, 1},
{-10.0, 8.0, 0, 1}, {-9.0, 8.0, 0, 1}, {-8.0, 8.0, 0, 1}, {-7.0, 8.0, 0, 1}, {-6.0, 8.0, 0, 1}, {-5.0, 8.0, 0, 1},
{-4.0, 8.0, 0, 1}, {-3.0, 8.0, 0, 1}, {-2.0, 8.0, 0, 1}, {-1.0, 8.0, 0, 1}, {3.0, 8.0, 0, 1}, {4.0, 8.0, 0, 1},
{5.0, 8.0, 0, 1}, {6.0, 8.0, 0, 1}, {7.0, 8.0, 0, 1}, {8.0, 8.0, 0, 1}, {9.0, 8.0, 0, 1}, {10.0, 8.0, 0, 1},
{14.0, 8.0, 0, 1}, {15.0, 8.0, 0, 1}, {16.0, 8.0, 0, 1}, {17.0, 8.0, 0, 1}, {18.0, 8.0, 0, 1}, {19.0, 8.0, 0, 1},
{20.0, 8.0, 0, 1}, {21.0, 8.0, 0, 1}, {-25.0, 9.0, 0, 1}, {-24.0, 9.0, 0, 1}, {-23.0, 9.0, 0, 1}, {-9.0, 9.0, 0, 1},
{-8.0, 9.0, 0, 1}, {-7.0, 9.0, 0, 1}, {-6.0, 9.0, 0, 1}, {-5.0, 9.0, 0, 1}, {-4.0, 9.0, 0, 1}, {-3.0, 9.0, 0, 1},
{-2.0, 9.0, 0, 1}, {-1.0, 9.0, 0, 1}, {3.0, 9.0, 0, 1}, {4.0, 9.0, 0, 1}, {5.0, 9.0, 0, 1}, {6.0, 9.0, 0, 1},
{7.0, 9.0, 0, 1}, {8.0, 9.0, 0, 1}, {9.0, 9.0, 0, 1}, {10.0, 9.0, 0, 1}, {14.0, 9.0, 0, 1}, {15.0, 9.0, 0, 1},
{16.0, 9.0, 0, 1}, {17.0, 9.0, 0, 1}, {18.0, 9.0, 0, 1}, {19.0, 9.0, 0, 1}, {20.0, 9.0, 0, 1}, {21.0, 9.0, 0, 1},
{-24.0, 10.0, 0, 1}, {-23.0, 10.0, 0, 1}, {-15.0, 10.0, 0, 1}, {-14.0, 10.0, 0, 1}, {-13.0, 10.0, 0, 1}, {-12.0, 10.0, 0, 1},
{-8.0, 10.0, 0, 1}, {-7.0, 10.0, 0, 1}, {-6.0, 10.0, 0, 1}, {-5.0, 10.0, 0, 1}, {-4.0, 10.0, 0, 1}, {-3.0, 10.0, 0, 1},
{-2.0, 10.0, 0, 1}, {-1.0, 10.0, 0, 1}, {4.0, 10.0, 0, 1}, {5.0, 10.0, 0, 1}, {6.0, 10.0, 0, 1}, {7.0, 10.0, 0, 1},
{8.0, 10.0, 0, 1}, {9.0, 10.0, 0, 1}, {10.0, 10.0, 0, 1}, {14.0, 10.0, 0, 1}, {15.0, 10.0, 0, 1}, {16.0, 10.0, 0, 1},
{17.0, 10.0, 0, 1}, {18.0, 10.0, 0, 1}, {19.0, 10.0, 0, 1}, {20.0, 10.0, 0, 1}, {21.0, 10.0, 0, 1}, {-24.0, 11.0, 0, 1},
{-23.0, 11.0, 0, 1}, {-22.0, 11.0, 0, 1}, {-16.0, 11.0, 0, 1}, {-15.0, 11.0, 0, 1}, {-14.0, 11.0, 0, 1}, {-13.0, 11.0, 0, 1},
{-12.0, 11.0, 0, 1}, {-11.0, 11.0, 0, 1}, {-7.0, 11.0, 0, 1}, {-6.0, 11.0, 0, 1}, {-5.0, 11.0, 0, 1}, {-4.0, 11.0, 0, 1},
{-3.0, 11.0, 0, 1}, {-2.0, 11.0, 0, 1}, {-1.0, 11.0, 0, 1}, {0.0, 11.0, 0, 1}, {4.0, 11.0, 0, 1}, {5.0, 11.0, 0, 1},
{6.0, 11.0, 0, 1}, {7.0, 11.0, 0, 1}, {8.0, 11.0, 0, 1}, {9.0, 11.0, 0, 1}, {10.0, 11.0, 0, 1}, {11.0, 11.0, 0, 1},
{15.0, 11.0, 0, 1}, {16.0, 11.0, 0, 1}, {17.0, 11.0, 0, 1}, {18.0, 11.0, 0, 1}, {19.0, 11.0, 0, 1}, {20.0, 11.0, 0, 1},
{-23.0, 12.0, 0, 1}, {-22.0, 12.0, 0, 1}, {-17.0, 12.0, 0, 1}, {-16.0, 12.0, 0, 1}, {-15.0, 12.0, 0, 1}, {-14.0, 12.0, 0, 1},
{-13.0, 12.0, 0, 1}, {-12.0, 12.0, 0, 1}, {-11.0, 12.0, 0, 1}, {-7.0, 12.0, 0, 1}, {-6.0, 12.0, 0, 1}, {-5.0, 12.0, 0, 1},
{-4.0, 12.0, 0, 1}, {-3.0, 12.0, 0, 1}, {-2.0, 12.0, 0, 1}, {-1.0, 12.0, 0, 1}, {0.0, 12.0, 0, 1}, {4.0, 12.0, 0, 1},
{5.0, 12.0, 0, 1}, {6.0, 12.0, 0, 1}, {7.0, 12.0, 0, 1}, {8.0, 12.0, 0, 1}, {9.0, 12.0, 0, 1}, {10.0, 12.0, 0, 1},
{11.0, 12.0, 0, 1}, {15.0, 12.0, 0, 1}, {16.0, 12.0, 0, 1}, {17.0, 12.0, 0, 1}, {18.0, 12.0, 0, 1}, {19.0, 12.0, 0, 1},
{-23.0, 13.0, 0, 1}, {-22.0, 13.0, 0, 1}, {-21.0, 13.0, 0, 1}, {-17.0, 13.0, 0, 1}, {-16.0, 13.0, 0, 1}, {-15.0, 13.0, 0, 1},
{-14.0, 13.0, 0, 1}, {-13.0, 13.0, 0, 1}, {-12.0, 13.0, 0, 1}, {-11.0, 13.0, 0, 1}, {-7.0, 13.0, 0, 1}, {-6.0, 13.0, 0, 1},
{-5.0, 13.0, 0, 1}, {-4.0, 13.0, 0, 1}, {-3.0, 13.0, 0, 1}, {-2.0, 13.0, 0, 1}, {-1.0, 13.0, 0, 1}, {0.0, 13.0, 0, 1},
{4.0, 13.0, 0, 1}, {5.0, 13.0, 0, 1}, {6.0, 13.0, 0, 1}, {7.0, 13.0, 0, 1}, {8.0, 13.0, 0, 1}, {9.0, 13.0, 0, 1},
{10.0, 13.0, 0, 1}, {11.0, 13.0, 0, 1}, {15.0, 13.0, 0, 1}, {16.0, 13.0, 0, 1}, {17.0, 13.0, 0, 1}, {18.0, 13.0, 0, 1},
{19.0, 13.0, 0, 1}, {-22.0, 14.0, 0, 1}, {-21.0, 14.0, 0, 1}, {-20.0, 14.0, 0, 1}, {-17.0, 14.0, 0, 1}, {-16.0, 14.0, 0, 1},
{-15.0, 14.0, 0, 1}, {-14.0, 14.0, 0, 1}, {-13.0, 14.0, 0, 1}, {-12.0, 14.0, 0, 1}, {-11.0, 14.0, 0, 1}, {-7.0, 14.0, 0, 1},
{-6.0, 14.0, 0, 1}, {-5.0, 14.0, 0, 1}, {-4.0, 14.0, 0, 1}, {-3.0, 14.0, 0, 1}, {-2.0, 14.0, 0, 1}, {-1.0, 14.0, 0, 1},
{0.0, 14.0, 0, 1}, {4.0, 14.0, 0, 1}, {5.0, 14.0, 0, 1}, {6.0, 14.0, 0, 1}, {7.0, 14.0, 0, 1}, {8.0, 14.0, 0, 1},
{9.0, 14.0, 0, 1}, {10.0, 14.0, 0, 1}, {11.0, 14.0, 0, 1}, {15.0, 14.0, 0, 1}, {16.0, 14.0, 0, 1}, {17.0, 14.0, 0, 1},
{18.0, 14.0, 0, 1}, {-21.0, 15.0, 0, 1}, {-20.0, 15.0, 0, 1}, {-17.0, 15.0, 0, 1}, {-16.0, 15.0, 0, 1}, {-15.0, 15.0, 0, 1},
{-14.0, 15.0, 0, 1}, {-13.0, 15.0, 0, 1}, {-12.0, 15.0, 0, 1}, {-11.0, 15.0, 0, 1}, {-7.0, 15.0, 0, 1}, {-6.0, 15.0, 0, 1},
{-5.0, 15.0, 0, 1}, {-4.0, 15.0, 0, 1}, {-3.0, 15.0, 0, 1}, {-2.0, 15.0, 0, 1}, {-1.0, 15.0, 0, 1}, {0.0, 15.0, 0, 1},
{4.0, 15.0, 0, 1}, {5.0, 15.0, 0, 1}, {6.0, 15.0, 0, 1}, {7.0, 15.0, 0, 1}, {8.0, 15.0, 0, 1}, {9.0, 15.0, 0, 1},
{10.0, 15.0, 0, 1}, {11.0, 15.0, 0, 1}, {-21.0, 16.0, 0, 1}, {-20.0, 16.0, 0, 1}, {-19.0, 16.0, 0, 1}, {-16.0, 16.0, 0, 1},
{-15.0, 16.0, 0, 1}, {-14.0, 16.0, 0, 1}, {-13.0, 16.0, 0, 1}, {-12.0, 16.0, 0, 1}, {-7.0, 16.0, 0, 1}, {-6.0, 16.0, 0, 1},
{-5.0, 16.0, 0, 1}, {-4.0, 16.0, 0, 1}, {-3.0, 16.0, 0, 1}, {-2.0, 16.0, 0, 1}, {-1.0, 16.0, 0, 1}, {0.0, 16.0, 0, 1},
{4.0, 16.0, 0, 1}, {5.0, 16.0, 0, 1}, {6.0, 16.0, 0, 1}, {7.0, 16.0, 0, 1}, {8.0, 16.0, 0, 1}, {9.0, 16.0, 0, 1},
{10.0, 16.0, 0, 1}, {11.0, 16.0, 0, 1}, {-20.0, 17.0, 0, 1}, {-19.0, 17.0, 0, 1}, {-18.0, 17.0, 0, 1}, {-7.0, 17.0, 0, 1},
{-6.0, 17.0, 0, 1}, {-5.0, 17.0, 0, 1}, {-4.0, 17.0, 0, 1}, {-3.0, 17.0, 0, 1}, {-2.0, 17.0, 0, 1}, {-1.0, 17.0, 0, 1},
{0.0, 17.0, 0, 1}, {4.0, 17.0, 0, 1}, {5.0, 17.0, 0, 1}, {6.0, 17.0, 0, 1}, {7.0, 17.0, 0, 1}, {8.0, 17.0, 0, 1},
{9.0, 17.0, 0, 1}, {10.0, 17.0, 0, 1}, {11.0, 17.0, 0, 1}, {19.0, 17.0, 0, 1}, {-19.0, 18.0, 0, 1}, {-18.0, 18.0, 0, 1},
{-17.0, 18.0, 0, 1}, {-7.0, 18.0, 0, 1}, {-6.0, 18.0, 0, 1}, {-5.0, 18.0, 0, 1}, {-4.0, 18.0, 0, 1}, {-3.0, 18.0, 0, 1},
{-2.0, 18.0, 0, 1}, {-1.0, 18.0, 0, 1}, {0.0, 18.0, 0, 1}, {4.0, 18.0, 0, 1}, {5.0, 18.0, 0, 1}, {6.0, 18.0, 0, 1},
{7.0, 18.0, 0, 1}, {8.0, 18.0, 0, 1}, {9.0, 18.0, 0, 1}, {10.0, 18.0, 0, 1}, {11.0, 18.0, 0, 1}, {18.0, 18.0, 0, 1},
{19.0, 18.0, 0, 1}, {20.0, 18.0, 0, 1}, {-18.0, 19.0, 0, 1}, {-17.0, 19.0, 0, 1}, {-16.0, 19.0, 0, 1}, {-15.0, 19.0, 0, 1},
{-8.0, 19.0, 0, 1}, {-7.0, 19.0, 0, 1}, {-6.0, 19.0, 0, 1}, {-5.0, 19.0, 0, 1}, {-4.0, 19.0, 0, 1}, {-3.0, 19.0, 0, 1},
{-2.0, 19.0, 0, 1}, {-1.0, 19.0, 0, 1}, {4.0, 19.0, 0, 1}, {5.0, 19.0, 0, 1}, {6.0, 19.0, 0, 1}, {7.0, 19.0, 0, 1},
{8.0, 19.0, 0, 1}, {9.0, 19.0, 0, 1}, {10.0, 19.0, 0, 1}, {17.0, 19.0, 0, 1}, {18.0, 19.0, 0, 1}, {19.0, 19.0, 0, 1},
{-17.0, 20.0, 0, 1}, {-16.0, 20.0, 0, 1}, {-15.0, 20.0, 0, 1}, {-14.0, 20.0, 0, 1}, {-7.0, 20.0, 0, 1}, {-6.0, 20.0, 0, 1},
{-5.0, 20.0, 0, 1}, {-4.0, 20.0, 0, 1}, {-3.0, 20.0, 0, 1}, {-2.0, 20.0, 0, 1}, {-1.0, 20.0, 0, 1}, {4.0, 20.0, 0, 1},
{5.0, 20.0, 0, 1}, {6.0, 20.0, 0, 1}, {7.0, 20.0, 0, 1}, {8.0, 20.0, 0, 1}, {9.0, 20.0, 0, 1}, {16.0, 20.0, 0, 1},
{17.0, 20.0, 0, 1}, {18.0, 20.0, 0, 1}, {-15.0, 21.0, 0, 1}, {-14.0, 21.0, 0, 1}, {-13.0, 21.0, 0, 1}, {-12.0, 21.0, 0, 1},
{-5.0, 21.0, 0, 1}, {-4.0, 21.0, 0, 1}, {-3.0, 21.0, 0, 1}, {-2.0, 21.0, 0, 1}, {-1.0, 21.0, 0, 1}, {14.0, 21.0, 0, 1},
{15.0, 21.0, 0, 1}, {16.0, 21.0, 0, 1}, {17.0, 21.0, 0, 1}, {-14.0, 22.0, 0, 1}, {-13.0, 22.0, 0, 1}, {-12.0, 22.0, 0, 1},
{-11.0, 22.0, 0, 1}, {-10.0, 22.0, 0, 1}, {12.0, 22.0, 0, 1}, {13.0, 22.0, 0, 1}, {14.0, 22.0, 0, 1}, {15.0, 22.0, 0, 1},
{-12.0, 23.0, 0, 1}, {-11.0, 23.0, 0, 1}, {-10.0, 23.0, 0, 1}, {-9.0, 23.0, 0, 1}, {-8.0, 23.0, 0, 1}, {9.0, 23.0, 0, 1},
{10.0, 23.0, 0, 1}, {11.0, 23.0, 0, 1}, {12.0, 23.0, 0, 1}, {13.0, 23.0, 0, 1}, {14.0, 23.0, 0, 1}, {-10.0, 24.0, 0, 1},
{-9.0, 24.0, 0, 1}, {-8.0, 24.0, 0, 1}, {-7.0, 24.0, 0, 1}, {-6.0, 24.0, 0, 1}, {-5.0, 24.0, 0, 1}, {-4.0, 24.0, 0, 1},
{-3.0, 24.0, 0, 1}, {5.0, 24.0, 0, 1}, {6.0, 24.0, 0, 1}, {7.0, 24.0, 0, 1}, {8.0, 24.0, 0, 1}, {9.0, 24.0, 0, 1},
{10.0, 24.0, 0, 1}, {11.0, 24.0, 0, 1}, {12.0, 24.0, 0, 1}, {-7.0, 25.0, 0, 1}, {-6.0, 25.0, 0, 1}, {-5.0, 25.0, 0, 1},
{-4.0, 25.0, 0, 1}, {-3.0, 25.0, 0, 1}, {-2.0, 25.0, 0, 1}, {-1.0, 25.0, 0, 1}, {0.0, 25.0, 0, 1}, {1.0, 25.0, 0, 1},
{2.0, 25.0, 0, 1}, {3.0, 25.0, 0, 1}, {4.0, 25.0, 0, 1}, {5.0, 25.0, 0, 1}, {6.0, 25.0, 0, 1}, {7.0, 25.0, 0, 1},
{8.0, 25.0, 0, 1}, {9.0, 25.0, 0, 1}, {-3.0, 26.0, 0, 1}, {-2.0, 26.0, 0, 1}, {-1.0, 26.0, 0, 1}, {0.0, 26.0, 0, 1},
{1.0, 26.0, 0, 1}, {2.0, 26.0, 0, 1}, {3.0, 26.0, 0, 1}, {4.0, 26.0, 0, 1}, {5.0, 26.0, 0, 1}
};
#endif // CONFIG_3D_OBJECT_ESP_LOGO

View File

@@ -0,0 +1,21 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
extern const uint8_t image_bmp_array_esp_logo[512];
extern const float image_3d_matrix_esp_logo[1427][4];
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,252 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_text.h"
const uint8_t image_bmp_array_esp_text[384] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3f, 0xf8, 0x7f, 0xf1, 0xff, 0xe1, 0xff, 0xe0, 0x7f, 0xe0, 0xff, 0xc1, 0xff, 0xc7, 0x07, 0xfe,
0x7f, 0xf8, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf0, 0xff, 0xe1, 0xff, 0xc3, 0xff, 0xc7, 0x0f, 0xfe,
0x7f, 0xf8, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xe3, 0xff, 0xc3, 0xff, 0xc7, 0x1f, 0xfe,
0x70, 0x00, 0xe0, 0x01, 0xe0, 0x79, 0xe0, 0x71, 0xc0, 0x03, 0x80, 0x07, 0x80, 0x07, 0x1e, 0x00,
0x70, 0x00, 0xe0, 0x01, 0xe0, 0x39, 0xe0, 0x71, 0xc0, 0x03, 0x80, 0x07, 0x80, 0x07, 0x1c, 0x00,
0x70, 0x00, 0xe0, 0x01, 0xe0, 0x39, 0xe0, 0x71, 0xc0, 0x03, 0x80, 0x07, 0x80, 0x07, 0x1c, 0x00,
0x70, 0x00, 0xe0, 0x01, 0xe0, 0x39, 0xe0, 0x71, 0xc0, 0x03, 0x80, 0x07, 0x80, 0x07, 0x1c, 0x00,
0x70, 0x00, 0xe0, 0x01, 0xe0, 0x39, 0xe0, 0x71, 0xc0, 0x03, 0x80, 0x07, 0x80, 0x07, 0x1c, 0x00,
0x70, 0x00, 0xe0, 0x01, 0xe0, 0x39, 0xe0, 0x71, 0xc0, 0x03, 0x80, 0x07, 0x80, 0x07, 0x1c, 0x00,
0x7f, 0xf0, 0xff, 0xe1, 0xe0, 0x79, 0xe0, 0x71, 0xff, 0xc3, 0xff, 0x83, 0xff, 0x87, 0x1f, 0xfc,
0x7f, 0xf0, 0xff, 0xf1, 0xff, 0xf9, 0xff, 0xf1, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xc7, 0x1f, 0xfc,
0x7f, 0xf0, 0x7f, 0xf1, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xc1, 0xff, 0xe1, 0xff, 0xc7, 0x1f, 0xfc,
0x70, 0x00, 0x00, 0x79, 0xff, 0xf1, 0xff, 0xe1, 0xc0, 0x00, 0x01, 0xe0, 0x03, 0xc7, 0x1c, 0x00,
0x70, 0x00, 0x00, 0x79, 0xff, 0xc1, 0xe1, 0xe1, 0xc0, 0x00, 0x00, 0xe0, 0x01, 0xc7, 0x1c, 0x00,
0x70, 0x00, 0x00, 0x79, 0xe0, 0x01, 0xe0, 0xe1, 0xc0, 0x00, 0x00, 0xe0, 0x01, 0xc7, 0x1c, 0x00,
0x70, 0x00, 0x00, 0x79, 0xe0, 0x01, 0xe0, 0x71, 0xc0, 0x00, 0x00, 0xe0, 0x01, 0xc7, 0x1c, 0x00,
0x70, 0x00, 0x00, 0x79, 0xe0, 0x01, 0xe0, 0x71, 0xc0, 0x00, 0x00, 0xe0, 0x01, 0xc7, 0x1c, 0x00,
0x70, 0x00, 0x00, 0x79, 0xe0, 0x01, 0xe0, 0x71, 0xc0, 0x00, 0x00, 0xe0, 0x01, 0xc7, 0x1c, 0x00,
0x70, 0x00, 0x00, 0x79, 0xe0, 0x01, 0xe0, 0x71, 0xc0, 0x00, 0x00, 0xe0, 0x01, 0xc7, 0x1c, 0x00,
0x7f, 0xf8, 0xff, 0xf1, 0xe0, 0x01, 0xe0, 0x79, 0xff, 0xe3, 0xff, 0xe7, 0xff, 0xc7, 0x1c, 0x00,
0x7f, 0xf8, 0xff, 0xf1, 0xe0, 0x01, 0xe0, 0x38, 0xff, 0xe3, 0xff, 0xc7, 0xff, 0xc7, 0x1c, 0x00,
0x3f, 0xf8, 0xff, 0xe1, 0xe0, 0x01, 0xe0, 0x38, 0xff, 0xe3, 0xff, 0x87, 0xff, 0x87, 0x1c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const float image_3d_array_esp_text[1271][4] = {
{-62.0, -11.0, 0, 1}, {-61.0, -11.0, 0, 1}, {-60.0, -11.0, 0, 1}, {-59.0, -11.0, 0, 1}, {-58.0, -11.0, 0, 1}, {-57.0, -11.0, 0, 1},
{-56.0, -11.0, 0, 1}, {-55.0, -11.0, 0, 1}, {-54.0, -11.0, 0, 1}, {-53.0, -11.0, 0, 1}, {-52.0, -11.0, 0, 1}, {-47.0, -11.0, 0, 1},
{-46.0, -11.0, 0, 1}, {-45.0, -11.0, 0, 1}, {-44.0, -11.0, 0, 1}, {-43.0, -11.0, 0, 1}, {-42.0, -11.0, 0, 1}, {-41.0, -11.0, 0, 1},
{-40.0, -11.0, 0, 1}, {-39.0, -11.0, 0, 1}, {-38.0, -11.0, 0, 1}, {-37.0, -11.0, 0, 1}, {-33.0, -11.0, 0, 1}, {-32.0, -11.0, 0, 1},
{-31.0, -11.0, 0, 1}, {-30.0, -11.0, 0, 1}, {-29.0, -11.0, 0, 1}, {-28.0, -11.0, 0, 1}, {-27.0, -11.0, 0, 1}, {-26.0, -11.0, 0, 1},
{-25.0, -11.0, 0, 1}, {-24.0, -11.0, 0, 1}, {-23.0, -11.0, 0, 1}, {-22.0, -11.0, 0, 1}, {-17.0, -11.0, 0, 1}, {-16.0, -11.0, 0, 1},
{-15.0, -11.0, 0, 1}, {-14.0, -11.0, 0, 1}, {-13.0, -11.0, 0, 1}, {-12.0, -11.0, 0, 1}, {-11.0, -11.0, 0, 1}, {-10.0, -11.0, 0, 1},
{-9.0, -11.0, 0, 1}, {-8.0, -11.0, 0, 1}, {-7.0, -11.0, 0, 1}, {-6.0, -11.0, 0, 1}, {1.0, -11.0, 0, 1}, {2.0, -11.0, 0, 1},
{3.0, -11.0, 0, 1}, {4.0, -11.0, 0, 1}, {5.0, -11.0, 0, 1}, {6.0, -11.0, 0, 1}, {7.0, -11.0, 0, 1}, {8.0, -11.0, 0, 1},
{9.0, -11.0, 0, 1}, {10.0, -11.0, 0, 1}, {16.0, -11.0, 0, 1}, {17.0, -11.0, 0, 1}, {18.0, -11.0, 0, 1}, {19.0, -11.0, 0, 1},
{20.0, -11.0, 0, 1}, {21.0, -11.0, 0, 1}, {22.0, -11.0, 0, 1}, {23.0, -11.0, 0, 1}, {24.0, -11.0, 0, 1}, {25.0, -11.0, 0, 1},
{31.0, -11.0, 0, 1}, {32.0, -11.0, 0, 1}, {33.0, -11.0, 0, 1}, {34.0, -11.0, 0, 1}, {35.0, -11.0, 0, 1}, {36.0, -11.0, 0, 1},
{37.0, -11.0, 0, 1}, {38.0, -11.0, 0, 1}, {39.0, -11.0, 0, 1}, {40.0, -11.0, 0, 1}, {41.0, -11.0, 0, 1}, {45.0, -11.0, 0, 1},
{46.0, -11.0, 0, 1}, {47.0, -11.0, 0, 1}, {53.0, -11.0, 0, 1}, {54.0, -11.0, 0, 1}, {55.0, -11.0, 0, 1}, {56.0, -11.0, 0, 1},
{57.0, -11.0, 0, 1}, {58.0, -11.0, 0, 1}, {59.0, -11.0, 0, 1}, {60.0, -11.0, 0, 1}, {61.0, -11.0, 0, 1}, {62.0, -11.0, 0, 1},
{-63.0, -10.0, 0, 1}, {-62.0, -10.0, 0, 1}, {-61.0, -10.0, 0, 1}, {-60.0, -10.0, 0, 1}, {-59.0, -10.0, 0, 1}, {-58.0, -10.0, 0, 1},
{-57.0, -10.0, 0, 1}, {-56.0, -10.0, 0, 1}, {-55.0, -10.0, 0, 1}, {-54.0, -10.0, 0, 1}, {-53.0, -10.0, 0, 1}, {-52.0, -10.0, 0, 1},
{-48.0, -10.0, 0, 1}, {-47.0, -10.0, 0, 1}, {-46.0, -10.0, 0, 1}, {-45.0, -10.0, 0, 1}, {-44.0, -10.0, 0, 1}, {-43.0, -10.0, 0, 1},
{-42.0, -10.0, 0, 1}, {-41.0, -10.0, 0, 1}, {-40.0, -10.0, 0, 1}, {-39.0, -10.0, 0, 1}, {-38.0, -10.0, 0, 1}, {-37.0, -10.0, 0, 1},
{-33.0, -10.0, 0, 1}, {-32.0, -10.0, 0, 1}, {-31.0, -10.0, 0, 1}, {-30.0, -10.0, 0, 1}, {-29.0, -10.0, 0, 1}, {-28.0, -10.0, 0, 1},
{-27.0, -10.0, 0, 1}, {-26.0, -10.0, 0, 1}, {-25.0, -10.0, 0, 1}, {-24.0, -10.0, 0, 1}, {-23.0, -10.0, 0, 1}, {-22.0, -10.0, 0, 1},
{-21.0, -10.0, 0, 1}, {-17.0, -10.0, 0, 1}, {-16.0, -10.0, 0, 1}, {-15.0, -10.0, 0, 1}, {-14.0, -10.0, 0, 1}, {-13.0, -10.0, 0, 1},
{-12.0, -10.0, 0, 1}, {-11.0, -10.0, 0, 1}, {-10.0, -10.0, 0, 1}, {-9.0, -10.0, 0, 1}, {-8.0, -10.0, 0, 1}, {-7.0, -10.0, 0, 1},
{-6.0, -10.0, 0, 1}, {-5.0, -10.0, 0, 1}, {0.0, -10.0, 0, 1}, {1.0, -10.0, 0, 1}, {2.0, -10.0, 0, 1}, {3.0, -10.0, 0, 1},
{4.0, -10.0, 0, 1}, {5.0, -10.0, 0, 1}, {6.0, -10.0, 0, 1}, {7.0, -10.0, 0, 1}, {8.0, -10.0, 0, 1}, {9.0, -10.0, 0, 1},
{10.0, -10.0, 0, 1}, {15.0, -10.0, 0, 1}, {16.0, -10.0, 0, 1}, {17.0, -10.0, 0, 1}, {18.0, -10.0, 0, 1}, {19.0, -10.0, 0, 1},
{20.0, -10.0, 0, 1}, {21.0, -10.0, 0, 1}, {22.0, -10.0, 0, 1}, {23.0, -10.0, 0, 1}, {24.0, -10.0, 0, 1}, {25.0, -10.0, 0, 1},
{30.0, -10.0, 0, 1}, {31.0, -10.0, 0, 1}, {32.0, -10.0, 0, 1}, {33.0, -10.0, 0, 1}, {34.0, -10.0, 0, 1}, {35.0, -10.0, 0, 1},
{36.0, -10.0, 0, 1}, {37.0, -10.0, 0, 1}, {38.0, -10.0, 0, 1}, {39.0, -10.0, 0, 1}, {40.0, -10.0, 0, 1}, {41.0, -10.0, 0, 1},
{45.0, -10.0, 0, 1}, {46.0, -10.0, 0, 1}, {47.0, -10.0, 0, 1}, {52.0, -10.0, 0, 1}, {53.0, -10.0, 0, 1}, {54.0, -10.0, 0, 1},
{55.0, -10.0, 0, 1}, {56.0, -10.0, 0, 1}, {57.0, -10.0, 0, 1}, {58.0, -10.0, 0, 1}, {59.0, -10.0, 0, 1}, {60.0, -10.0, 0, 1},
{61.0, -10.0, 0, 1}, {62.0, -10.0, 0, 1}, {-63.0, -9.0, 0, 1}, {-62.0, -9.0, 0, 1}, {-61.0, -9.0, 0, 1}, {-60.0, -9.0, 0, 1},
{-59.0, -9.0, 0, 1}, {-58.0, -9.0, 0, 1}, {-57.0, -9.0, 0, 1}, {-56.0, -9.0, 0, 1}, {-55.0, -9.0, 0, 1}, {-54.0, -9.0, 0, 1},
{-53.0, -9.0, 0, 1}, {-52.0, -9.0, 0, 1}, {-48.0, -9.0, 0, 1}, {-47.0, -9.0, 0, 1}, {-46.0, -9.0, 0, 1}, {-45.0, -9.0, 0, 1},
{-44.0, -9.0, 0, 1}, {-43.0, -9.0, 0, 1}, {-42.0, -9.0, 0, 1}, {-41.0, -9.0, 0, 1}, {-40.0, -9.0, 0, 1}, {-39.0, -9.0, 0, 1},
{-38.0, -9.0, 0, 1}, {-37.0, -9.0, 0, 1}, {-33.0, -9.0, 0, 1}, {-32.0, -9.0, 0, 1}, {-31.0, -9.0, 0, 1}, {-30.0, -9.0, 0, 1},
{-29.0, -9.0, 0, 1}, {-28.0, -9.0, 0, 1}, {-27.0, -9.0, 0, 1}, {-26.0, -9.0, 0, 1}, {-25.0, -9.0, 0, 1}, {-24.0, -9.0, 0, 1},
{-23.0, -9.0, 0, 1}, {-22.0, -9.0, 0, 1}, {-21.0, -9.0, 0, 1}, {-17.0, -9.0, 0, 1}, {-16.0, -9.0, 0, 1}, {-15.0, -9.0, 0, 1},
{-14.0, -9.0, 0, 1}, {-13.0, -9.0, 0, 1}, {-12.0, -9.0, 0, 1}, {-11.0, -9.0, 0, 1}, {-10.0, -9.0, 0, 1}, {-9.0, -9.0, 0, 1},
{-8.0, -9.0, 0, 1}, {-7.0, -9.0, 0, 1}, {-6.0, -9.0, 0, 1}, {-5.0, -9.0, 0, 1}, {-1.0, -9.0, 0, 1}, {0.0, -9.0, 0, 1},
{1.0, -9.0, 0, 1}, {2.0, -9.0, 0, 1}, {3.0, -9.0, 0, 1}, {4.0, -9.0, 0, 1}, {5.0, -9.0, 0, 1}, {6.0, -9.0, 0, 1},
{7.0, -9.0, 0, 1}, {8.0, -9.0, 0, 1}, {9.0, -9.0, 0, 1}, {10.0, -9.0, 0, 1}, {14.0, -9.0, 0, 1}, {15.0, -9.0, 0, 1},
{16.0, -9.0, 0, 1}, {17.0, -9.0, 0, 1}, {18.0, -9.0, 0, 1}, {19.0, -9.0, 0, 1}, {20.0, -9.0, 0, 1}, {21.0, -9.0, 0, 1},
{22.0, -9.0, 0, 1}, {23.0, -9.0, 0, 1}, {24.0, -9.0, 0, 1}, {25.0, -9.0, 0, 1}, {30.0, -9.0, 0, 1}, {31.0, -9.0, 0, 1},
{32.0, -9.0, 0, 1}, {33.0, -9.0, 0, 1}, {34.0, -9.0, 0, 1}, {35.0, -9.0, 0, 1}, {36.0, -9.0, 0, 1}, {37.0, -9.0, 0, 1},
{38.0, -9.0, 0, 1}, {39.0, -9.0, 0, 1}, {40.0, -9.0, 0, 1}, {41.0, -9.0, 0, 1}, {45.0, -9.0, 0, 1}, {46.0, -9.0, 0, 1},
{47.0, -9.0, 0, 1}, {51.0, -9.0, 0, 1}, {52.0, -9.0, 0, 1}, {53.0, -9.0, 0, 1}, {54.0, -9.0, 0, 1}, {55.0, -9.0, 0, 1},
{56.0, -9.0, 0, 1}, {57.0, -9.0, 0, 1}, {58.0, -9.0, 0, 1}, {59.0, -9.0, 0, 1}, {60.0, -9.0, 0, 1}, {61.0, -9.0, 0, 1},
{62.0, -9.0, 0, 1}, {-63.0, -8.0, 0, 1}, {-62.0, -8.0, 0, 1}, {-61.0, -8.0, 0, 1}, {-48.0, -8.0, 0, 1}, {-47.0, -8.0, 0, 1},
{-46.0, -8.0, 0, 1}, {-33.0, -8.0, 0, 1}, {-32.0, -8.0, 0, 1}, {-31.0, -8.0, 0, 1}, {-30.0, -8.0, 0, 1}, {-23.0, -8.0, 0, 1},
{-22.0, -8.0, 0, 1}, {-21.0, -8.0, 0, 1}, {-20.0, -8.0, 0, 1}, {-17.0, -8.0, 0, 1}, {-16.0, -8.0, 0, 1}, {-15.0, -8.0, 0, 1},
{-14.0, -8.0, 0, 1}, {-7.0, -8.0, 0, 1}, {-6.0, -8.0, 0, 1}, {-5.0, -8.0, 0, 1}, {-1.0, -8.0, 0, 1}, {0.0, -8.0, 0, 1},
{1.0, -8.0, 0, 1}, {14.0, -8.0, 0, 1}, {15.0, -8.0, 0, 1}, {16.0, -8.0, 0, 1}, {29.0, -8.0, 0, 1}, {30.0, -8.0, 0, 1},
{31.0, -8.0, 0, 1}, {32.0, -8.0, 0, 1}, {45.0, -8.0, 0, 1}, {46.0, -8.0, 0, 1}, {47.0, -8.0, 0, 1}, {51.0, -8.0, 0, 1},
{52.0, -8.0, 0, 1}, {53.0, -8.0, 0, 1}, {54.0, -8.0, 0, 1}, {-63.0, -7.0, 0, 1}, {-62.0, -7.0, 0, 1}, {-61.0, -7.0, 0, 1},
{-48.0, -7.0, 0, 1}, {-47.0, -7.0, 0, 1}, {-46.0, -7.0, 0, 1}, {-33.0, -7.0, 0, 1}, {-32.0, -7.0, 0, 1}, {-31.0, -7.0, 0, 1},
{-30.0, -7.0, 0, 1}, {-22.0, -7.0, 0, 1}, {-21.0, -7.0, 0, 1}, {-20.0, -7.0, 0, 1}, {-17.0, -7.0, 0, 1}, {-16.0, -7.0, 0, 1},
{-15.0, -7.0, 0, 1}, {-14.0, -7.0, 0, 1}, {-7.0, -7.0, 0, 1}, {-6.0, -7.0, 0, 1}, {-5.0, -7.0, 0, 1}, {-1.0, -7.0, 0, 1},
{0.0, -7.0, 0, 1}, {1.0, -7.0, 0, 1}, {14.0, -7.0, 0, 1}, {15.0, -7.0, 0, 1}, {16.0, -7.0, 0, 1}, {29.0, -7.0, 0, 1},
{30.0, -7.0, 0, 1}, {31.0, -7.0, 0, 1}, {32.0, -7.0, 0, 1}, {45.0, -7.0, 0, 1}, {46.0, -7.0, 0, 1}, {47.0, -7.0, 0, 1},
{51.0, -7.0, 0, 1}, {52.0, -7.0, 0, 1}, {53.0, -7.0, 0, 1}, {-63.0, -6.0, 0, 1}, {-62.0, -6.0, 0, 1}, {-61.0, -6.0, 0, 1},
{-48.0, -6.0, 0, 1}, {-47.0, -6.0, 0, 1}, {-46.0, -6.0, 0, 1}, {-33.0, -6.0, 0, 1}, {-32.0, -6.0, 0, 1}, {-31.0, -6.0, 0, 1},
{-30.0, -6.0, 0, 1}, {-22.0, -6.0, 0, 1}, {-21.0, -6.0, 0, 1}, {-20.0, -6.0, 0, 1}, {-17.0, -6.0, 0, 1}, {-16.0, -6.0, 0, 1},
{-15.0, -6.0, 0, 1}, {-14.0, -6.0, 0, 1}, {-7.0, -6.0, 0, 1}, {-6.0, -6.0, 0, 1}, {-5.0, -6.0, 0, 1}, {-1.0, -6.0, 0, 1},
{0.0, -6.0, 0, 1}, {1.0, -6.0, 0, 1}, {14.0, -6.0, 0, 1}, {15.0, -6.0, 0, 1}, {16.0, -6.0, 0, 1}, {29.0, -6.0, 0, 1},
{30.0, -6.0, 0, 1}, {31.0, -6.0, 0, 1}, {32.0, -6.0, 0, 1}, {45.0, -6.0, 0, 1}, {46.0, -6.0, 0, 1}, {47.0, -6.0, 0, 1},
{51.0, -6.0, 0, 1}, {52.0, -6.0, 0, 1}, {53.0, -6.0, 0, 1}, {-63.0, -5.0, 0, 1}, {-62.0, -5.0, 0, 1}, {-61.0, -5.0, 0, 1},
{-48.0, -5.0, 0, 1}, {-47.0, -5.0, 0, 1}, {-46.0, -5.0, 0, 1}, {-33.0, -5.0, 0, 1}, {-32.0, -5.0, 0, 1}, {-31.0, -5.0, 0, 1},
{-30.0, -5.0, 0, 1}, {-22.0, -5.0, 0, 1}, {-21.0, -5.0, 0, 1}, {-20.0, -5.0, 0, 1}, {-17.0, -5.0, 0, 1}, {-16.0, -5.0, 0, 1},
{-15.0, -5.0, 0, 1}, {-14.0, -5.0, 0, 1}, {-7.0, -5.0, 0, 1}, {-6.0, -5.0, 0, 1}, {-5.0, -5.0, 0, 1}, {-1.0, -5.0, 0, 1},
{0.0, -5.0, 0, 1}, {1.0, -5.0, 0, 1}, {14.0, -5.0, 0, 1}, {15.0, -5.0, 0, 1}, {16.0, -5.0, 0, 1}, {29.0, -5.0, 0, 1},
{30.0, -5.0, 0, 1}, {31.0, -5.0, 0, 1}, {32.0, -5.0, 0, 1}, {45.0, -5.0, 0, 1}, {46.0, -5.0, 0, 1}, {47.0, -5.0, 0, 1},
{51.0, -5.0, 0, 1}, {52.0, -5.0, 0, 1}, {53.0, -5.0, 0, 1}, {-63.0, -4.0, 0, 1}, {-62.0, -4.0, 0, 1}, {-61.0, -4.0, 0, 1},
{-48.0, -4.0, 0, 1}, {-47.0, -4.0, 0, 1}, {-46.0, -4.0, 0, 1}, {-33.0, -4.0, 0, 1}, {-32.0, -4.0, 0, 1}, {-31.0, -4.0, 0, 1},
{-30.0, -4.0, 0, 1}, {-22.0, -4.0, 0, 1}, {-21.0, -4.0, 0, 1}, {-20.0, -4.0, 0, 1}, {-17.0, -4.0, 0, 1}, {-16.0, -4.0, 0, 1},
{-15.0, -4.0, 0, 1}, {-14.0, -4.0, 0, 1}, {-7.0, -4.0, 0, 1}, {-6.0, -4.0, 0, 1}, {-5.0, -4.0, 0, 1}, {-1.0, -4.0, 0, 1},
{0.0, -4.0, 0, 1}, {1.0, -4.0, 0, 1}, {14.0, -4.0, 0, 1}, {15.0, -4.0, 0, 1}, {16.0, -4.0, 0, 1}, {29.0, -4.0, 0, 1},
{30.0, -4.0, 0, 1}, {31.0, -4.0, 0, 1}, {32.0, -4.0, 0, 1}, {45.0, -4.0, 0, 1}, {46.0, -4.0, 0, 1}, {47.0, -4.0, 0, 1},
{51.0, -4.0, 0, 1}, {52.0, -4.0, 0, 1}, {53.0, -4.0, 0, 1}, {-63.0, -3.0, 0, 1}, {-62.0, -3.0, 0, 1}, {-61.0, -3.0, 0, 1},
{-48.0, -3.0, 0, 1}, {-47.0, -3.0, 0, 1}, {-46.0, -3.0, 0, 1}, {-33.0, -3.0, 0, 1}, {-32.0, -3.0, 0, 1}, {-31.0, -3.0, 0, 1},
{-30.0, -3.0, 0, 1}, {-22.0, -3.0, 0, 1}, {-21.0, -3.0, 0, 1}, {-20.0, -3.0, 0, 1}, {-17.0, -3.0, 0, 1}, {-16.0, -3.0, 0, 1},
{-15.0, -3.0, 0, 1}, {-14.0, -3.0, 0, 1}, {-7.0, -3.0, 0, 1}, {-6.0, -3.0, 0, 1}, {-5.0, -3.0, 0, 1}, {-1.0, -3.0, 0, 1},
{0.0, -3.0, 0, 1}, {1.0, -3.0, 0, 1}, {14.0, -3.0, 0, 1}, {15.0, -3.0, 0, 1}, {16.0, -3.0, 0, 1}, {29.0, -3.0, 0, 1},
{30.0, -3.0, 0, 1}, {31.0, -3.0, 0, 1}, {32.0, -3.0, 0, 1}, {45.0, -3.0, 0, 1}, {46.0, -3.0, 0, 1}, {47.0, -3.0, 0, 1},
{51.0, -3.0, 0, 1}, {52.0, -3.0, 0, 1}, {53.0, -3.0, 0, 1}, {-63.0, -2.0, 0, 1}, {-62.0, -2.0, 0, 1}, {-61.0, -2.0, 0, 1},
{-60.0, -2.0, 0, 1}, {-59.0, -2.0, 0, 1}, {-58.0, -2.0, 0, 1}, {-57.0, -2.0, 0, 1}, {-56.0, -2.0, 0, 1}, {-55.0, -2.0, 0, 1},
{-54.0, -2.0, 0, 1}, {-53.0, -2.0, 0, 1}, {-48.0, -2.0, 0, 1}, {-47.0, -2.0, 0, 1}, {-46.0, -2.0, 0, 1}, {-45.0, -2.0, 0, 1},
{-44.0, -2.0, 0, 1}, {-43.0, -2.0, 0, 1}, {-42.0, -2.0, 0, 1}, {-41.0, -2.0, 0, 1}, {-40.0, -2.0, 0, 1}, {-39.0, -2.0, 0, 1},
{-38.0, -2.0, 0, 1}, {-33.0, -2.0, 0, 1}, {-32.0, -2.0, 0, 1}, {-31.0, -2.0, 0, 1}, {-30.0, -2.0, 0, 1}, {-23.0, -2.0, 0, 1},
{-22.0, -2.0, 0, 1}, {-21.0, -2.0, 0, 1}, {-20.0, -2.0, 0, 1}, {-17.0, -2.0, 0, 1}, {-16.0, -2.0, 0, 1}, {-15.0, -2.0, 0, 1},
{-14.0, -2.0, 0, 1}, {-7.0, -2.0, 0, 1}, {-6.0, -2.0, 0, 1}, {-5.0, -2.0, 0, 1}, {-1.0, -2.0, 0, 1}, {0.0, -2.0, 0, 1},
{1.0, -2.0, 0, 1}, {2.0, -2.0, 0, 1}, {3.0, -2.0, 0, 1}, {4.0, -2.0, 0, 1}, {5.0, -2.0, 0, 1}, {6.0, -2.0, 0, 1},
{7.0, -2.0, 0, 1}, {8.0, -2.0, 0, 1}, {9.0, -2.0, 0, 1}, {14.0, -2.0, 0, 1}, {15.0, -2.0, 0, 1}, {16.0, -2.0, 0, 1},
{17.0, -2.0, 0, 1}, {18.0, -2.0, 0, 1}, {19.0, -2.0, 0, 1}, {20.0, -2.0, 0, 1}, {21.0, -2.0, 0, 1}, {22.0, -2.0, 0, 1},
{23.0, -2.0, 0, 1}, {24.0, -2.0, 0, 1}, {30.0, -2.0, 0, 1}, {31.0, -2.0, 0, 1}, {32.0, -2.0, 0, 1}, {33.0, -2.0, 0, 1},
{34.0, -2.0, 0, 1}, {35.0, -2.0, 0, 1}, {36.0, -2.0, 0, 1}, {37.0, -2.0, 0, 1}, {38.0, -2.0, 0, 1}, {39.0, -2.0, 0, 1},
{40.0, -2.0, 0, 1}, {45.0, -2.0, 0, 1}, {46.0, -2.0, 0, 1}, {47.0, -2.0, 0, 1}, {51.0, -2.0, 0, 1}, {52.0, -2.0, 0, 1},
{53.0, -2.0, 0, 1}, {54.0, -2.0, 0, 1}, {55.0, -2.0, 0, 1}, {56.0, -2.0, 0, 1}, {57.0, -2.0, 0, 1}, {58.0, -2.0, 0, 1},
{59.0, -2.0, 0, 1}, {60.0, -2.0, 0, 1}, {61.0, -2.0, 0, 1}, {-63.0, -1.0, 0, 1}, {-62.0, -1.0, 0, 1}, {-61.0, -1.0, 0, 1},
{-60.0, -1.0, 0, 1}, {-59.0, -1.0, 0, 1}, {-58.0, -1.0, 0, 1}, {-57.0, -1.0, 0, 1}, {-56.0, -1.0, 0, 1}, {-55.0, -1.0, 0, 1},
{-54.0, -1.0, 0, 1}, {-53.0, -1.0, 0, 1}, {-48.0, -1.0, 0, 1}, {-47.0, -1.0, 0, 1}, {-46.0, -1.0, 0, 1}, {-45.0, -1.0, 0, 1},
{-44.0, -1.0, 0, 1}, {-43.0, -1.0, 0, 1}, {-42.0, -1.0, 0, 1}, {-41.0, -1.0, 0, 1}, {-40.0, -1.0, 0, 1}, {-39.0, -1.0, 0, 1},
{-38.0, -1.0, 0, 1}, {-37.0, -1.0, 0, 1}, {-33.0, -1.0, 0, 1}, {-32.0, -1.0, 0, 1}, {-31.0, -1.0, 0, 1}, {-30.0, -1.0, 0, 1},
{-29.0, -1.0, 0, 1}, {-28.0, -1.0, 0, 1}, {-27.0, -1.0, 0, 1}, {-26.0, -1.0, 0, 1}, {-25.0, -1.0, 0, 1}, {-24.0, -1.0, 0, 1},
{-23.0, -1.0, 0, 1}, {-22.0, -1.0, 0, 1}, {-21.0, -1.0, 0, 1}, {-20.0, -1.0, 0, 1}, {-17.0, -1.0, 0, 1}, {-16.0, -1.0, 0, 1},
{-15.0, -1.0, 0, 1}, {-14.0, -1.0, 0, 1}, {-13.0, -1.0, 0, 1}, {-12.0, -1.0, 0, 1}, {-11.0, -1.0, 0, 1}, {-10.0, -1.0, 0, 1},
{-9.0, -1.0, 0, 1}, {-8.0, -1.0, 0, 1}, {-7.0, -1.0, 0, 1}, {-6.0, -1.0, 0, 1}, {-5.0, -1.0, 0, 1}, {-1.0, -1.0, 0, 1},
{0.0, -1.0, 0, 1}, {1.0, -1.0, 0, 1}, {2.0, -1.0, 0, 1}, {3.0, -1.0, 0, 1}, {4.0, -1.0, 0, 1}, {5.0, -1.0, 0, 1},
{6.0, -1.0, 0, 1}, {7.0, -1.0, 0, 1}, {8.0, -1.0, 0, 1}, {9.0, -1.0, 0, 1}, {14.0, -1.0, 0, 1}, {15.0, -1.0, 0, 1},
{16.0, -1.0, 0, 1}, {17.0, -1.0, 0, 1}, {18.0, -1.0, 0, 1}, {19.0, -1.0, 0, 1}, {20.0, -1.0, 0, 1}, {21.0, -1.0, 0, 1},
{22.0, -1.0, 0, 1}, {23.0, -1.0, 0, 1}, {24.0, -1.0, 0, 1}, {25.0, -1.0, 0, 1}, {30.0, -1.0, 0, 1}, {31.0, -1.0, 0, 1},
{32.0, -1.0, 0, 1}, {33.0, -1.0, 0, 1}, {34.0, -1.0, 0, 1}, {35.0, -1.0, 0, 1}, {36.0, -1.0, 0, 1}, {37.0, -1.0, 0, 1},
{38.0, -1.0, 0, 1}, {39.0, -1.0, 0, 1}, {40.0, -1.0, 0, 1}, {41.0, -1.0, 0, 1}, {45.0, -1.0, 0, 1}, {46.0, -1.0, 0, 1},
{47.0, -1.0, 0, 1}, {51.0, -1.0, 0, 1}, {52.0, -1.0, 0, 1}, {53.0, -1.0, 0, 1}, {54.0, -1.0, 0, 1}, {55.0, -1.0, 0, 1},
{56.0, -1.0, 0, 1}, {57.0, -1.0, 0, 1}, {58.0, -1.0, 0, 1}, {59.0, -1.0, 0, 1}, {60.0, -1.0, 0, 1}, {61.0, -1.0, 0, 1},
{-63.0, 0.0, 0, 1}, {-62.0, 0.0, 0, 1}, {-61.0, 0.0, 0, 1}, {-60.0, 0.0, 0, 1}, {-59.0, 0.0, 0, 1}, {-58.0, 0.0, 0, 1},
{-57.0, 0.0, 0, 1}, {-56.0, 0.0, 0, 1}, {-55.0, 0.0, 0, 1}, {-54.0, 0.0, 0, 1}, {-53.0, 0.0, 0, 1}, {-47.0, 0.0, 0, 1},
{-46.0, 0.0, 0, 1}, {-45.0, 0.0, 0, 1}, {-44.0, 0.0, 0, 1}, {-43.0, 0.0, 0, 1}, {-42.0, 0.0, 0, 1}, {-41.0, 0.0, 0, 1},
{-40.0, 0.0, 0, 1}, {-39.0, 0.0, 0, 1}, {-38.0, 0.0, 0, 1}, {-37.0, 0.0, 0, 1}, {-33.0, 0.0, 0, 1}, {-32.0, 0.0, 0, 1},
{-31.0, 0.0, 0, 1}, {-30.0, 0.0, 0, 1}, {-29.0, 0.0, 0, 1}, {-28.0, 0.0, 0, 1}, {-27.0, 0.0, 0, 1}, {-26.0, 0.0, 0, 1},
{-25.0, 0.0, 0, 1}, {-24.0, 0.0, 0, 1}, {-23.0, 0.0, 0, 1}, {-22.0, 0.0, 0, 1}, {-21.0, 0.0, 0, 1}, {-17.0, 0.0, 0, 1},
{-16.0, 0.0, 0, 1}, {-15.0, 0.0, 0, 1}, {-14.0, 0.0, 0, 1}, {-13.0, 0.0, 0, 1}, {-12.0, 0.0, 0, 1}, {-11.0, 0.0, 0, 1},
{-10.0, 0.0, 0, 1}, {-9.0, 0.0, 0, 1}, {-8.0, 0.0, 0, 1}, {-7.0, 0.0, 0, 1}, {-6.0, 0.0, 0, 1}, {-5.0, 0.0, 0, 1},
{-1.0, 0.0, 0, 1}, {0.0, 0.0, 0, 1}, {1.0, 0.0, 0, 1}, {2.0, 0.0, 0, 1}, {3.0, 0.0, 0, 1}, {4.0, 0.0, 0, 1},
{5.0, 0.0, 0, 1}, {6.0, 0.0, 0, 1}, {7.0, 0.0, 0, 1}, {8.0, 0.0, 0, 1}, {9.0, 0.0, 0, 1}, {15.0, 0.0, 0, 1},
{16.0, 0.0, 0, 1}, {17.0, 0.0, 0, 1}, {18.0, 0.0, 0, 1}, {19.0, 0.0, 0, 1}, {20.0, 0.0, 0, 1}, {21.0, 0.0, 0, 1},
{22.0, 0.0, 0, 1}, {23.0, 0.0, 0, 1}, {24.0, 0.0, 0, 1}, {25.0, 0.0, 0, 1}, {26.0, 0.0, 0, 1}, {31.0, 0.0, 0, 1},
{32.0, 0.0, 0, 1}, {33.0, 0.0, 0, 1}, {34.0, 0.0, 0, 1}, {35.0, 0.0, 0, 1}, {36.0, 0.0, 0, 1}, {37.0, 0.0, 0, 1},
{38.0, 0.0, 0, 1}, {39.0, 0.0, 0, 1}, {40.0, 0.0, 0, 1}, {41.0, 0.0, 0, 1}, {45.0, 0.0, 0, 1}, {46.0, 0.0, 0, 1},
{47.0, 0.0, 0, 1}, {51.0, 0.0, 0, 1}, {52.0, 0.0, 0, 1}, {53.0, 0.0, 0, 1}, {54.0, 0.0, 0, 1}, {55.0, 0.0, 0, 1},
{56.0, 0.0, 0, 1}, {57.0, 0.0, 0, 1}, {58.0, 0.0, 0, 1}, {59.0, 0.0, 0, 1}, {60.0, 0.0, 0, 1}, {61.0, 0.0, 0, 1},
{-63.0, 1.0, 0, 1}, {-62.0, 1.0, 0, 1}, {-61.0, 1.0, 0, 1}, {-39.0, 1.0, 0, 1}, {-38.0, 1.0, 0, 1}, {-37.0, 1.0, 0, 1},
{-36.0, 1.0, 0, 1}, {-33.0, 1.0, 0, 1}, {-32.0, 1.0, 0, 1}, {-31.0, 1.0, 0, 1}, {-30.0, 1.0, 0, 1}, {-29.0, 1.0, 0, 1},
{-28.0, 1.0, 0, 1}, {-27.0, 1.0, 0, 1}, {-26.0, 1.0, 0, 1}, {-25.0, 1.0, 0, 1}, {-24.0, 1.0, 0, 1}, {-23.0, 1.0, 0, 1},
{-22.0, 1.0, 0, 1}, {-21.0, 1.0, 0, 1}, {-17.0, 1.0, 0, 1}, {-16.0, 1.0, 0, 1}, {-15.0, 1.0, 0, 1}, {-14.0, 1.0, 0, 1},
{-13.0, 1.0, 0, 1}, {-12.0, 1.0, 0, 1}, {-11.0, 1.0, 0, 1}, {-10.0, 1.0, 0, 1}, {-9.0, 1.0, 0, 1}, {-8.0, 1.0, 0, 1},
{-7.0, 1.0, 0, 1}, {-6.0, 1.0, 0, 1}, {-1.0, 1.0, 0, 1}, {0.0, 1.0, 0, 1}, {1.0, 1.0, 0, 1}, {23.0, 1.0, 0, 1},
{24.0, 1.0, 0, 1}, {25.0, 1.0, 0, 1}, {26.0, 1.0, 0, 1}, {38.0, 1.0, 0, 1}, {39.0, 1.0, 0, 1}, {40.0, 1.0, 0, 1},
{41.0, 1.0, 0, 1}, {45.0, 1.0, 0, 1}, {46.0, 1.0, 0, 1}, {47.0, 1.0, 0, 1}, {51.0, 1.0, 0, 1}, {52.0, 1.0, 0, 1},
{53.0, 1.0, 0, 1}, {-63.0, 2.0, 0, 1}, {-62.0, 2.0, 0, 1}, {-61.0, 2.0, 0, 1}, {-39.0, 2.0, 0, 1}, {-38.0, 2.0, 0, 1},
{-37.0, 2.0, 0, 1}, {-36.0, 2.0, 0, 1}, {-33.0, 2.0, 0, 1}, {-32.0, 2.0, 0, 1}, {-31.0, 2.0, 0, 1}, {-30.0, 2.0, 0, 1},
{-29.0, 2.0, 0, 1}, {-28.0, 2.0, 0, 1}, {-27.0, 2.0, 0, 1}, {-26.0, 2.0, 0, 1}, {-25.0, 2.0, 0, 1}, {-24.0, 2.0, 0, 1},
{-23.0, 2.0, 0, 1}, {-17.0, 2.0, 0, 1}, {-16.0, 2.0, 0, 1}, {-15.0, 2.0, 0, 1}, {-14.0, 2.0, 0, 1}, {-9.0, 2.0, 0, 1},
{-8.0, 2.0, 0, 1}, {-7.0, 2.0, 0, 1}, {-6.0, 2.0, 0, 1}, {-1.0, 2.0, 0, 1}, {0.0, 2.0, 0, 1}, {1.0, 2.0, 0, 1},
{24.0, 2.0, 0, 1}, {25.0, 2.0, 0, 1}, {26.0, 2.0, 0, 1}, {39.0, 2.0, 0, 1}, {40.0, 2.0, 0, 1}, {41.0, 2.0, 0, 1},
{45.0, 2.0, 0, 1}, {46.0, 2.0, 0, 1}, {47.0, 2.0, 0, 1}, {51.0, 2.0, 0, 1}, {52.0, 2.0, 0, 1}, {53.0, 2.0, 0, 1},
{-63.0, 3.0, 0, 1}, {-62.0, 3.0, 0, 1}, {-61.0, 3.0, 0, 1}, {-39.0, 3.0, 0, 1}, {-38.0, 3.0, 0, 1}, {-37.0, 3.0, 0, 1},
{-36.0, 3.0, 0, 1}, {-33.0, 3.0, 0, 1}, {-32.0, 3.0, 0, 1}, {-31.0, 3.0, 0, 1}, {-30.0, 3.0, 0, 1}, {-17.0, 3.0, 0, 1},
{-16.0, 3.0, 0, 1}, {-15.0, 3.0, 0, 1}, {-14.0, 3.0, 0, 1}, {-8.0, 3.0, 0, 1}, {-7.0, 3.0, 0, 1}, {-6.0, 3.0, 0, 1},
{-1.0, 3.0, 0, 1}, {0.0, 3.0, 0, 1}, {1.0, 3.0, 0, 1}, {24.0, 3.0, 0, 1}, {25.0, 3.0, 0, 1}, {26.0, 3.0, 0, 1},
{39.0, 3.0, 0, 1}, {40.0, 3.0, 0, 1}, {41.0, 3.0, 0, 1}, {45.0, 3.0, 0, 1}, {46.0, 3.0, 0, 1}, {47.0, 3.0, 0, 1},
{51.0, 3.0, 0, 1}, {52.0, 3.0, 0, 1}, {53.0, 3.0, 0, 1}, {-63.0, 4.0, 0, 1}, {-62.0, 4.0, 0, 1}, {-61.0, 4.0, 0, 1},
{-39.0, 4.0, 0, 1}, {-38.0, 4.0, 0, 1}, {-37.0, 4.0, 0, 1}, {-36.0, 4.0, 0, 1}, {-33.0, 4.0, 0, 1}, {-32.0, 4.0, 0, 1},
{-31.0, 4.0, 0, 1}, {-30.0, 4.0, 0, 1}, {-17.0, 4.0, 0, 1}, {-16.0, 4.0, 0, 1}, {-15.0, 4.0, 0, 1}, {-14.0, 4.0, 0, 1},
{-7.0, 4.0, 0, 1}, {-6.0, 4.0, 0, 1}, {-5.0, 4.0, 0, 1}, {-1.0, 4.0, 0, 1}, {0.0, 4.0, 0, 1}, {1.0, 4.0, 0, 1},
{24.0, 4.0, 0, 1}, {25.0, 4.0, 0, 1}, {26.0, 4.0, 0, 1}, {39.0, 4.0, 0, 1}, {40.0, 4.0, 0, 1}, {41.0, 4.0, 0, 1},
{45.0, 4.0, 0, 1}, {46.0, 4.0, 0, 1}, {47.0, 4.0, 0, 1}, {51.0, 4.0, 0, 1}, {52.0, 4.0, 0, 1}, {53.0, 4.0, 0, 1},
{-63.0, 5.0, 0, 1}, {-62.0, 5.0, 0, 1}, {-61.0, 5.0, 0, 1}, {-39.0, 5.0, 0, 1}, {-38.0, 5.0, 0, 1}, {-37.0, 5.0, 0, 1},
{-36.0, 5.0, 0, 1}, {-33.0, 5.0, 0, 1}, {-32.0, 5.0, 0, 1}, {-31.0, 5.0, 0, 1}, {-30.0, 5.0, 0, 1}, {-17.0, 5.0, 0, 1},
{-16.0, 5.0, 0, 1}, {-15.0, 5.0, 0, 1}, {-14.0, 5.0, 0, 1}, {-7.0, 5.0, 0, 1}, {-6.0, 5.0, 0, 1}, {-5.0, 5.0, 0, 1},
{-1.0, 5.0, 0, 1}, {0.0, 5.0, 0, 1}, {1.0, 5.0, 0, 1}, {24.0, 5.0, 0, 1}, {25.0, 5.0, 0, 1}, {26.0, 5.0, 0, 1},
{39.0, 5.0, 0, 1}, {40.0, 5.0, 0, 1}, {41.0, 5.0, 0, 1}, {45.0, 5.0, 0, 1}, {46.0, 5.0, 0, 1}, {47.0, 5.0, 0, 1},
{51.0, 5.0, 0, 1}, {52.0, 5.0, 0, 1}, {53.0, 5.0, 0, 1}, {-63.0, 6.0, 0, 1}, {-62.0, 6.0, 0, 1}, {-61.0, 6.0, 0, 1},
{-39.0, 6.0, 0, 1}, {-38.0, 6.0, 0, 1}, {-37.0, 6.0, 0, 1}, {-36.0, 6.0, 0, 1}, {-33.0, 6.0, 0, 1}, {-32.0, 6.0, 0, 1},
{-31.0, 6.0, 0, 1}, {-30.0, 6.0, 0, 1}, {-17.0, 6.0, 0, 1}, {-16.0, 6.0, 0, 1}, {-15.0, 6.0, 0, 1}, {-14.0, 6.0, 0, 1},
{-7.0, 6.0, 0, 1}, {-6.0, 6.0, 0, 1}, {-5.0, 6.0, 0, 1}, {-1.0, 6.0, 0, 1}, {0.0, 6.0, 0, 1}, {1.0, 6.0, 0, 1},
{24.0, 6.0, 0, 1}, {25.0, 6.0, 0, 1}, {26.0, 6.0, 0, 1}, {39.0, 6.0, 0, 1}, {40.0, 6.0, 0, 1}, {41.0, 6.0, 0, 1},
{45.0, 6.0, 0, 1}, {46.0, 6.0, 0, 1}, {47.0, 6.0, 0, 1}, {51.0, 6.0, 0, 1}, {52.0, 6.0, 0, 1}, {53.0, 6.0, 0, 1},
{-63.0, 7.0, 0, 1}, {-62.0, 7.0, 0, 1}, {-61.0, 7.0, 0, 1}, {-39.0, 7.0, 0, 1}, {-38.0, 7.0, 0, 1}, {-37.0, 7.0, 0, 1},
{-36.0, 7.0, 0, 1}, {-33.0, 7.0, 0, 1}, {-32.0, 7.0, 0, 1}, {-31.0, 7.0, 0, 1}, {-30.0, 7.0, 0, 1}, {-17.0, 7.0, 0, 1},
{-16.0, 7.0, 0, 1}, {-15.0, 7.0, 0, 1}, {-14.0, 7.0, 0, 1}, {-7.0, 7.0, 0, 1}, {-6.0, 7.0, 0, 1}, {-5.0, 7.0, 0, 1},
{-1.0, 7.0, 0, 1}, {0.0, 7.0, 0, 1}, {1.0, 7.0, 0, 1}, {24.0, 7.0, 0, 1}, {25.0, 7.0, 0, 1}, {26.0, 7.0, 0, 1},
{39.0, 7.0, 0, 1}, {40.0, 7.0, 0, 1}, {41.0, 7.0, 0, 1}, {45.0, 7.0, 0, 1}, {46.0, 7.0, 0, 1}, {47.0, 7.0, 0, 1},
{51.0, 7.0, 0, 1}, {52.0, 7.0, 0, 1}, {53.0, 7.0, 0, 1}, {-63.0, 8.0, 0, 1}, {-62.0, 8.0, 0, 1}, {-61.0, 8.0, 0, 1},
{-60.0, 8.0, 0, 1}, {-59.0, 8.0, 0, 1}, {-58.0, 8.0, 0, 1}, {-57.0, 8.0, 0, 1}, {-56.0, 8.0, 0, 1}, {-55.0, 8.0, 0, 1},
{-54.0, 8.0, 0, 1}, {-53.0, 8.0, 0, 1}, {-52.0, 8.0, 0, 1}, {-48.0, 8.0, 0, 1}, {-47.0, 8.0, 0, 1}, {-46.0, 8.0, 0, 1},
{-45.0, 8.0, 0, 1}, {-44.0, 8.0, 0, 1}, {-43.0, 8.0, 0, 1}, {-42.0, 8.0, 0, 1}, {-41.0, 8.0, 0, 1}, {-40.0, 8.0, 0, 1},
{-39.0, 8.0, 0, 1}, {-38.0, 8.0, 0, 1}, {-37.0, 8.0, 0, 1}, {-33.0, 8.0, 0, 1}, {-32.0, 8.0, 0, 1}, {-31.0, 8.0, 0, 1},
{-30.0, 8.0, 0, 1}, {-17.0, 8.0, 0, 1}, {-16.0, 8.0, 0, 1}, {-15.0, 8.0, 0, 1}, {-14.0, 8.0, 0, 1}, {-7.0, 8.0, 0, 1},
{-6.0, 8.0, 0, 1}, {-5.0, 8.0, 0, 1}, {-4.0, 8.0, 0, 1}, {-1.0, 8.0, 0, 1}, {0.0, 8.0, 0, 1}, {1.0, 8.0, 0, 1},
{2.0, 8.0, 0, 1}, {3.0, 8.0, 0, 1}, {4.0, 8.0, 0, 1}, {5.0, 8.0, 0, 1}, {6.0, 8.0, 0, 1}, {7.0, 8.0, 0, 1},
{8.0, 8.0, 0, 1}, {9.0, 8.0, 0, 1}, {10.0, 8.0, 0, 1}, {14.0, 8.0, 0, 1}, {15.0, 8.0, 0, 1}, {16.0, 8.0, 0, 1},
{17.0, 8.0, 0, 1}, {18.0, 8.0, 0, 1}, {19.0, 8.0, 0, 1}, {20.0, 8.0, 0, 1}, {21.0, 8.0, 0, 1}, {22.0, 8.0, 0, 1},
{23.0, 8.0, 0, 1}, {24.0, 8.0, 0, 1}, {25.0, 8.0, 0, 1}, {26.0, 8.0, 0, 1}, {29.0, 8.0, 0, 1}, {30.0, 8.0, 0, 1},
{31.0, 8.0, 0, 1}, {32.0, 8.0, 0, 1}, {33.0, 8.0, 0, 1}, {34.0, 8.0, 0, 1}, {35.0, 8.0, 0, 1}, {36.0, 8.0, 0, 1},
{37.0, 8.0, 0, 1}, {38.0, 8.0, 0, 1}, {39.0, 8.0, 0, 1}, {40.0, 8.0, 0, 1}, {41.0, 8.0, 0, 1}, {45.0, 8.0, 0, 1},
{46.0, 8.0, 0, 1}, {47.0, 8.0, 0, 1}, {51.0, 8.0, 0, 1}, {52.0, 8.0, 0, 1}, {53.0, 8.0, 0, 1}, {-63.0, 9.0, 0, 1},
{-62.0, 9.0, 0, 1}, {-61.0, 9.0, 0, 1}, {-60.0, 9.0, 0, 1}, {-59.0, 9.0, 0, 1}, {-58.0, 9.0, 0, 1}, {-57.0, 9.0, 0, 1},
{-56.0, 9.0, 0, 1}, {-55.0, 9.0, 0, 1}, {-54.0, 9.0, 0, 1}, {-53.0, 9.0, 0, 1}, {-52.0, 9.0, 0, 1}, {-48.0, 9.0, 0, 1},
{-47.0, 9.0, 0, 1}, {-46.0, 9.0, 0, 1}, {-45.0, 9.0, 0, 1}, {-44.0, 9.0, 0, 1}, {-43.0, 9.0, 0, 1}, {-42.0, 9.0, 0, 1},
{-41.0, 9.0, 0, 1}, {-40.0, 9.0, 0, 1}, {-39.0, 9.0, 0, 1}, {-38.0, 9.0, 0, 1}, {-37.0, 9.0, 0, 1}, {-33.0, 9.0, 0, 1},
{-32.0, 9.0, 0, 1}, {-31.0, 9.0, 0, 1}, {-30.0, 9.0, 0, 1}, {-17.0, 9.0, 0, 1}, {-16.0, 9.0, 0, 1}, {-15.0, 9.0, 0, 1},
{-14.0, 9.0, 0, 1}, {-6.0, 9.0, 0, 1}, {-5.0, 9.0, 0, 1}, {-4.0, 9.0, 0, 1}, {0.0, 9.0, 0, 1}, {1.0, 9.0, 0, 1},
{2.0, 9.0, 0, 1}, {3.0, 9.0, 0, 1}, {4.0, 9.0, 0, 1}, {5.0, 9.0, 0, 1}, {6.0, 9.0, 0, 1}, {7.0, 9.0, 0, 1},
{8.0, 9.0, 0, 1}, {9.0, 9.0, 0, 1}, {10.0, 9.0, 0, 1}, {14.0, 9.0, 0, 1}, {15.0, 9.0, 0, 1}, {16.0, 9.0, 0, 1},
{17.0, 9.0, 0, 1}, {18.0, 9.0, 0, 1}, {19.0, 9.0, 0, 1}, {20.0, 9.0, 0, 1}, {21.0, 9.0, 0, 1}, {22.0, 9.0, 0, 1},
{23.0, 9.0, 0, 1}, {24.0, 9.0, 0, 1}, {25.0, 9.0, 0, 1}, {29.0, 9.0, 0, 1}, {30.0, 9.0, 0, 1}, {31.0, 9.0, 0, 1},
{32.0, 9.0, 0, 1}, {33.0, 9.0, 0, 1}, {34.0, 9.0, 0, 1}, {35.0, 9.0, 0, 1}, {36.0, 9.0, 0, 1}, {37.0, 9.0, 0, 1},
{38.0, 9.0, 0, 1}, {39.0, 9.0, 0, 1}, {40.0, 9.0, 0, 1}, {41.0, 9.0, 0, 1}, {45.0, 9.0, 0, 1}, {46.0, 9.0, 0, 1},
{47.0, 9.0, 0, 1}, {51.0, 9.0, 0, 1}, {52.0, 9.0, 0, 1}, {53.0, 9.0, 0, 1}, {-62.0, 10.0, 0, 1}, {-61.0, 10.0, 0, 1},
{-60.0, 10.0, 0, 1}, {-59.0, 10.0, 0, 1}, {-58.0, 10.0, 0, 1}, {-57.0, 10.0, 0, 1}, {-56.0, 10.0, 0, 1}, {-55.0, 10.0, 0, 1},
{-54.0, 10.0, 0, 1}, {-53.0, 10.0, 0, 1}, {-52.0, 10.0, 0, 1}, {-48.0, 10.0, 0, 1}, {-47.0, 10.0, 0, 1}, {-46.0, 10.0, 0, 1},
{-45.0, 10.0, 0, 1}, {-44.0, 10.0, 0, 1}, {-43.0, 10.0, 0, 1}, {-42.0, 10.0, 0, 1}, {-41.0, 10.0, 0, 1}, {-40.0, 10.0, 0, 1},
{-39.0, 10.0, 0, 1}, {-38.0, 10.0, 0, 1}, {-33.0, 10.0, 0, 1}, {-32.0, 10.0, 0, 1}, {-31.0, 10.0, 0, 1}, {-30.0, 10.0, 0, 1},
{-17.0, 10.0, 0, 1}, {-16.0, 10.0, 0, 1}, {-15.0, 10.0, 0, 1}, {-14.0, 10.0, 0, 1}, {-6.0, 10.0, 0, 1}, {-5.0, 10.0, 0, 1},
{-4.0, 10.0, 0, 1}, {0.0, 10.0, 0, 1}, {1.0, 10.0, 0, 1}, {2.0, 10.0, 0, 1}, {3.0, 10.0, 0, 1}, {4.0, 10.0, 0, 1},
{5.0, 10.0, 0, 1}, {6.0, 10.0, 0, 1}, {7.0, 10.0, 0, 1}, {8.0, 10.0, 0, 1}, {9.0, 10.0, 0, 1}, {10.0, 10.0, 0, 1},
{14.0, 10.0, 0, 1}, {15.0, 10.0, 0, 1}, {16.0, 10.0, 0, 1}, {17.0, 10.0, 0, 1}, {18.0, 10.0, 0, 1}, {19.0, 10.0, 0, 1},
{20.0, 10.0, 0, 1}, {21.0, 10.0, 0, 1}, {22.0, 10.0, 0, 1}, {23.0, 10.0, 0, 1}, {24.0, 10.0, 0, 1}, {29.0, 10.0, 0, 1},
{30.0, 10.0, 0, 1}, {31.0, 10.0, 0, 1}, {32.0, 10.0, 0, 1}, {33.0, 10.0, 0, 1}, {34.0, 10.0, 0, 1}, {35.0, 10.0, 0, 1},
{36.0, 10.0, 0, 1}, {37.0, 10.0, 0, 1}, {38.0, 10.0, 0, 1}, {39.0, 10.0, 0, 1}, {40.0, 10.0, 0, 1}, {45.0, 10.0, 0, 1},
{46.0, 10.0, 0, 1}, {47.0, 10.0, 0, 1}, {51.0, 10.0, 0, 1}, {52.0, 10.0, 0, 1}, {53.0, 10.0, 0, 1}
};

View File

@@ -0,0 +1,16 @@
// File generated by image_to_3d_array.py
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
extern const uint8_t image_bmp_array_esp_text[384];
extern const float image_3d_array_esp_text[1271][4];
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,338 @@
// File generated by ImgTo3D.py
// Image file converted to 3D matrix cpu_logo.png
#include "image_to_3d_matrix.h"
#ifdef CONFIG_3D_OBJECT_CUSTOM
const uint8_t image_to_bmp_array_custom[512] = {
0x00, 0x00, 0x0e, 0x1c, 0x38, 0x70, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00,
0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00,
0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe,
0xff, 0xfe, 0x0f, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xfe, 0x0f, 0xff, 0xff, 0xf0, 0x7f, 0xff,
0xff, 0xfe, 0x0f, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0x00, 0x1e, 0x0f, 0xff, 0xff, 0xf0, 0x78, 0x00,
0x00, 0x1e, 0x0f, 0x00, 0x00, 0xf0, 0x78, 0x00, 0x00, 0x1e, 0x0f, 0x00, 0x00, 0xf0, 0x78, 0x00,
0x7f, 0xfe, 0x0f, 0x00, 0x00, 0xf0, 0x7f, 0xfe, 0xff, 0xfe, 0x0f, 0x00, 0x00, 0xf0, 0x7f, 0xff,
0xff, 0xfe, 0x0f, 0x00, 0x00, 0xf0, 0x7f, 0xff, 0xff, 0xfe, 0x0f, 0x00, 0x00, 0xf0, 0x7f, 0xff,
0x7f, 0xfe, 0x0f, 0x00, 0x00, 0xf0, 0x7f, 0xfc, 0x00, 0x1e, 0x0f, 0x00, 0x00, 0xf0, 0x78, 0x00,
0x00, 0x1e, 0x0f, 0x00, 0x00, 0xf0, 0x78, 0x00, 0x7f, 0xfe, 0x0f, 0x00, 0x00, 0xf0, 0x7f, 0xfe,
0xff, 0xfe, 0x0f, 0x00, 0x00, 0xf0, 0x7f, 0xff, 0xff, 0xfe, 0x0f, 0x00, 0x00, 0xf0, 0x7f, 0xff,
0xff, 0xfe, 0x0f, 0x00, 0x00, 0xf0, 0x7f, 0xff, 0x7f, 0xfe, 0x0f, 0x00, 0x00, 0xf0, 0x7f, 0xfe,
0x00, 0x1e, 0x0f, 0x00, 0x00, 0xf0, 0x78, 0x00, 0x00, 0x1e, 0x0f, 0x00, 0x00, 0xf0, 0x78, 0x00,
0x7f, 0xfe, 0x0f, 0xff, 0xff, 0xf0, 0x7f, 0xfc, 0xff, 0xfe, 0x0f, 0xff, 0xff, 0xf0, 0x7f, 0xff,
0xff, 0xfe, 0x0f, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xfe, 0x0f, 0xff, 0xff, 0xf0, 0x7f, 0xff,
0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00,
0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00,
0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3e, 0x7c, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x3c, 0x7c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1c, 0x38, 0x70, 0x00, 0x00
};
const float image_to_3d_matrix_custom[1732][4] = {
{-12.0, -32.0, 0, 1}, {-11.0, -32.0, 0, 1}, {-10.0, -32.0, 0, 1}, {-5.0, -32.0, 0, 1}, {-4.0, -32.0, 0, 1}, {-3.0, -32.0, 0, 1},
{2.0, -32.0, 0, 1}, {3.0, -32.0, 0, 1}, {4.0, -32.0, 0, 1}, {9.0, -32.0, 0, 1}, {10.0, -32.0, 0, 1}, {11.0, -32.0, 0, 1},
{-13.0, -31.0, 0, 1}, {-12.0, -31.0, 0, 1}, {-11.0, -31.0, 0, 1}, {-10.0, -31.0, 0, 1}, {-6.0, -31.0, 0, 1}, {-5.0, -31.0, 0, 1},
{-4.0, -31.0, 0, 1}, {-3.0, -31.0, 0, 1}, {-2.0, -31.0, 0, 1}, {1.0, -31.0, 0, 1}, {2.0, -31.0, 0, 1}, {3.0, -31.0, 0, 1},
{4.0, -31.0, 0, 1}, {5.0, -31.0, 0, 1}, {8.0, -31.0, 0, 1}, {9.0, -31.0, 0, 1}, {10.0, -31.0, 0, 1}, {11.0, -31.0, 0, 1},
{12.0, -31.0, 0, 1}, {-13.0, -30.0, 0, 1}, {-12.0, -30.0, 0, 1}, {-11.0, -30.0, 0, 1}, {-10.0, -30.0, 0, 1}, {-6.0, -30.0, 0, 1},
{-5.0, -30.0, 0, 1}, {-4.0, -30.0, 0, 1}, {-3.0, -30.0, 0, 1}, {-2.0, -30.0, 0, 1}, {1.0, -30.0, 0, 1}, {2.0, -30.0, 0, 1},
{3.0, -30.0, 0, 1}, {4.0, -30.0, 0, 1}, {5.0, -30.0, 0, 1}, {8.0, -30.0, 0, 1}, {9.0, -30.0, 0, 1}, {10.0, -30.0, 0, 1},
{11.0, -30.0, 0, 1}, {12.0, -30.0, 0, 1}, {-13.0, -29.0, 0, 1}, {-12.0, -29.0, 0, 1}, {-11.0, -29.0, 0, 1}, {-10.0, -29.0, 0, 1},
{-6.0, -29.0, 0, 1}, {-5.0, -29.0, 0, 1}, {-4.0, -29.0, 0, 1}, {-3.0, -29.0, 0, 1}, {-2.0, -29.0, 0, 1}, {1.0, -29.0, 0, 1},
{2.0, -29.0, 0, 1}, {3.0, -29.0, 0, 1}, {4.0, -29.0, 0, 1}, {5.0, -29.0, 0, 1}, {8.0, -29.0, 0, 1}, {9.0, -29.0, 0, 1},
{10.0, -29.0, 0, 1}, {11.0, -29.0, 0, 1}, {12.0, -29.0, 0, 1}, {-13.0, -28.0, 0, 1}, {-12.0, -28.0, 0, 1}, {-11.0, -28.0, 0, 1},
{-10.0, -28.0, 0, 1}, {-6.0, -28.0, 0, 1}, {-5.0, -28.0, 0, 1}, {-4.0, -28.0, 0, 1}, {-3.0, -28.0, 0, 1}, {-2.0, -28.0, 0, 1},
{1.0, -28.0, 0, 1}, {2.0, -28.0, 0, 1}, {3.0, -28.0, 0, 1}, {4.0, -28.0, 0, 1}, {5.0, -28.0, 0, 1}, {8.0, -28.0, 0, 1},
{9.0, -28.0, 0, 1}, {10.0, -28.0, 0, 1}, {11.0, -28.0, 0, 1}, {12.0, -28.0, 0, 1}, {-13.0, -27.0, 0, 1}, {-12.0, -27.0, 0, 1},
{-11.0, -27.0, 0, 1}, {-10.0, -27.0, 0, 1}, {-6.0, -27.0, 0, 1}, {-5.0, -27.0, 0, 1}, {-4.0, -27.0, 0, 1}, {-3.0, -27.0, 0, 1},
{-2.0, -27.0, 0, 1}, {1.0, -27.0, 0, 1}, {2.0, -27.0, 0, 1}, {3.0, -27.0, 0, 1}, {4.0, -27.0, 0, 1}, {5.0, -27.0, 0, 1},
{8.0, -27.0, 0, 1}, {9.0, -27.0, 0, 1}, {10.0, -27.0, 0, 1}, {11.0, -27.0, 0, 1}, {12.0, -27.0, 0, 1}, {-13.0, -26.0, 0, 1},
{-12.0, -26.0, 0, 1}, {-11.0, -26.0, 0, 1}, {-10.0, -26.0, 0, 1}, {-6.0, -26.0, 0, 1}, {-5.0, -26.0, 0, 1}, {-4.0, -26.0, 0, 1},
{-3.0, -26.0, 0, 1}, {-2.0, -26.0, 0, 1}, {1.0, -26.0, 0, 1}, {2.0, -26.0, 0, 1}, {3.0, -26.0, 0, 1}, {4.0, -26.0, 0, 1},
{5.0, -26.0, 0, 1}, {8.0, -26.0, 0, 1}, {9.0, -26.0, 0, 1}, {10.0, -26.0, 0, 1}, {11.0, -26.0, 0, 1}, {12.0, -26.0, 0, 1},
{-13.0, -25.0, 0, 1}, {-12.0, -25.0, 0, 1}, {-11.0, -25.0, 0, 1}, {-10.0, -25.0, 0, 1}, {-6.0, -25.0, 0, 1}, {-5.0, -25.0, 0, 1},
{-4.0, -25.0, 0, 1}, {-3.0, -25.0, 0, 1}, {-2.0, -25.0, 0, 1}, {1.0, -25.0, 0, 1}, {2.0, -25.0, 0, 1}, {3.0, -25.0, 0, 1},
{4.0, -25.0, 0, 1}, {5.0, -25.0, 0, 1}, {8.0, -25.0, 0, 1}, {9.0, -25.0, 0, 1}, {10.0, -25.0, 0, 1}, {11.0, -25.0, 0, 1},
{12.0, -25.0, 0, 1}, {-13.0, -24.0, 0, 1}, {-12.0, -24.0, 0, 1}, {-11.0, -24.0, 0, 1}, {-10.0, -24.0, 0, 1}, {-6.0, -24.0, 0, 1},
{-5.0, -24.0, 0, 1}, {-4.0, -24.0, 0, 1}, {-3.0, -24.0, 0, 1}, {-2.0, -24.0, 0, 1}, {1.0, -24.0, 0, 1}, {2.0, -24.0, 0, 1},
{3.0, -24.0, 0, 1}, {4.0, -24.0, 0, 1}, {5.0, -24.0, 0, 1}, {8.0, -24.0, 0, 1}, {9.0, -24.0, 0, 1}, {10.0, -24.0, 0, 1},
{11.0, -24.0, 0, 1}, {12.0, -24.0, 0, 1}, {-13.0, -23.0, 0, 1}, {-12.0, -23.0, 0, 1}, {-11.0, -23.0, 0, 1}, {-10.0, -23.0, 0, 1},
{-6.0, -23.0, 0, 1}, {-5.0, -23.0, 0, 1}, {-4.0, -23.0, 0, 1}, {-3.0, -23.0, 0, 1}, {-2.0, -23.0, 0, 1}, {1.0, -23.0, 0, 1},
{2.0, -23.0, 0, 1}, {3.0, -23.0, 0, 1}, {4.0, -23.0, 0, 1}, {5.0, -23.0, 0, 1}, {8.0, -23.0, 0, 1}, {9.0, -23.0, 0, 1},
{10.0, -23.0, 0, 1}, {11.0, -23.0, 0, 1}, {12.0, -23.0, 0, 1}, {-13.0, -22.0, 0, 1}, {-12.0, -22.0, 0, 1}, {-11.0, -22.0, 0, 1},
{-10.0, -22.0, 0, 1}, {-6.0, -22.0, 0, 1}, {-5.0, -22.0, 0, 1}, {-4.0, -22.0, 0, 1}, {-3.0, -22.0, 0, 1}, {-2.0, -22.0, 0, 1},
{1.0, -22.0, 0, 1}, {2.0, -22.0, 0, 1}, {3.0, -22.0, 0, 1}, {4.0, -22.0, 0, 1}, {5.0, -22.0, 0, 1}, {8.0, -22.0, 0, 1},
{9.0, -22.0, 0, 1}, {10.0, -22.0, 0, 1}, {11.0, -22.0, 0, 1}, {12.0, -22.0, 0, 1}, {-21.0, -21.0, 0, 1}, {-20.0, -21.0, 0, 1},
{-19.0, -21.0, 0, 1}, {-18.0, -21.0, 0, 1}, {-17.0, -21.0, 0, 1}, {-16.0, -21.0, 0, 1}, {-15.0, -21.0, 0, 1}, {-14.0, -21.0, 0, 1},
{-13.0, -21.0, 0, 1}, {-12.0, -21.0, 0, 1}, {-11.0, -21.0, 0, 1}, {-10.0, -21.0, 0, 1}, {-9.0, -21.0, 0, 1}, {-8.0, -21.0, 0, 1},
{-7.0, -21.0, 0, 1}, {-6.0, -21.0, 0, 1}, {-5.0, -21.0, 0, 1}, {-4.0, -21.0, 0, 1}, {-3.0, -21.0, 0, 1}, {-2.0, -21.0, 0, 1},
{-1.0, -21.0, 0, 1}, {0.0, -21.0, 0, 1}, {1.0, -21.0, 0, 1}, {2.0, -21.0, 0, 1}, {3.0, -21.0, 0, 1}, {4.0, -21.0, 0, 1},
{5.0, -21.0, 0, 1}, {6.0, -21.0, 0, 1}, {7.0, -21.0, 0, 1}, {8.0, -21.0, 0, 1}, {9.0, -21.0, 0, 1}, {10.0, -21.0, 0, 1},
{11.0, -21.0, 0, 1}, {12.0, -21.0, 0, 1}, {13.0, -21.0, 0, 1}, {14.0, -21.0, 0, 1}, {15.0, -21.0, 0, 1}, {16.0, -21.0, 0, 1},
{17.0, -21.0, 0, 1}, {18.0, -21.0, 0, 1}, {19.0, -21.0, 0, 1}, {20.0, -21.0, 0, 1}, {-21.0, -20.0, 0, 1}, {-20.0, -20.0, 0, 1},
{-19.0, -20.0, 0, 1}, {-18.0, -20.0, 0, 1}, {-17.0, -20.0, 0, 1}, {-16.0, -20.0, 0, 1}, {-15.0, -20.0, 0, 1}, {-14.0, -20.0, 0, 1},
{-13.0, -20.0, 0, 1}, {-12.0, -20.0, 0, 1}, {-11.0, -20.0, 0, 1}, {-10.0, -20.0, 0, 1}, {-9.0, -20.0, 0, 1}, {-8.0, -20.0, 0, 1},
{-7.0, -20.0, 0, 1}, {-6.0, -20.0, 0, 1}, {-5.0, -20.0, 0, 1}, {-4.0, -20.0, 0, 1}, {-3.0, -20.0, 0, 1}, {-2.0, -20.0, 0, 1},
{-1.0, -20.0, 0, 1}, {0.0, -20.0, 0, 1}, {1.0, -20.0, 0, 1}, {2.0, -20.0, 0, 1}, {3.0, -20.0, 0, 1}, {4.0, -20.0, 0, 1},
{5.0, -20.0, 0, 1}, {6.0, -20.0, 0, 1}, {7.0, -20.0, 0, 1}, {8.0, -20.0, 0, 1}, {9.0, -20.0, 0, 1}, {10.0, -20.0, 0, 1},
{11.0, -20.0, 0, 1}, {12.0, -20.0, 0, 1}, {13.0, -20.0, 0, 1}, {14.0, -20.0, 0, 1}, {15.0, -20.0, 0, 1}, {16.0, -20.0, 0, 1},
{17.0, -20.0, 0, 1}, {18.0, -20.0, 0, 1}, {19.0, -20.0, 0, 1}, {20.0, -20.0, 0, 1}, {-21.0, -19.0, 0, 1}, {-20.0, -19.0, 0, 1},
{-19.0, -19.0, 0, 1}, {-18.0, -19.0, 0, 1}, {-17.0, -19.0, 0, 1}, {-16.0, -19.0, 0, 1}, {-15.0, -19.0, 0, 1}, {-14.0, -19.0, 0, 1},
{-13.0, -19.0, 0, 1}, {-12.0, -19.0, 0, 1}, {-11.0, -19.0, 0, 1}, {-10.0, -19.0, 0, 1}, {-9.0, -19.0, 0, 1}, {-8.0, -19.0, 0, 1},
{-7.0, -19.0, 0, 1}, {-6.0, -19.0, 0, 1}, {-5.0, -19.0, 0, 1}, {-4.0, -19.0, 0, 1}, {-3.0, -19.0, 0, 1}, {-2.0, -19.0, 0, 1},
{-1.0, -19.0, 0, 1}, {0.0, -19.0, 0, 1}, {1.0, -19.0, 0, 1}, {2.0, -19.0, 0, 1}, {3.0, -19.0, 0, 1}, {4.0, -19.0, 0, 1},
{5.0, -19.0, 0, 1}, {6.0, -19.0, 0, 1}, {7.0, -19.0, 0, 1}, {8.0, -19.0, 0, 1}, {9.0, -19.0, 0, 1}, {10.0, -19.0, 0, 1},
{11.0, -19.0, 0, 1}, {12.0, -19.0, 0, 1}, {13.0, -19.0, 0, 1}, {14.0, -19.0, 0, 1}, {15.0, -19.0, 0, 1}, {16.0, -19.0, 0, 1},
{17.0, -19.0, 0, 1}, {18.0, -19.0, 0, 1}, {19.0, -19.0, 0, 1}, {20.0, -19.0, 0, 1}, {-21.0, -18.0, 0, 1}, {-20.0, -18.0, 0, 1},
{-19.0, -18.0, 0, 1}, {-18.0, -18.0, 0, 1}, {-17.0, -18.0, 0, 1}, {-16.0, -18.0, 0, 1}, {-15.0, -18.0, 0, 1}, {-14.0, -18.0, 0, 1},
{-13.0, -18.0, 0, 1}, {-12.0, -18.0, 0, 1}, {-11.0, -18.0, 0, 1}, {-10.0, -18.0, 0, 1}, {-9.0, -18.0, 0, 1}, {-8.0, -18.0, 0, 1},
{-7.0, -18.0, 0, 1}, {-6.0, -18.0, 0, 1}, {-5.0, -18.0, 0, 1}, {-4.0, -18.0, 0, 1}, {-3.0, -18.0, 0, 1}, {-2.0, -18.0, 0, 1},
{-1.0, -18.0, 0, 1}, {0.0, -18.0, 0, 1}, {1.0, -18.0, 0, 1}, {2.0, -18.0, 0, 1}, {3.0, -18.0, 0, 1}, {4.0, -18.0, 0, 1},
{5.0, -18.0, 0, 1}, {6.0, -18.0, 0, 1}, {7.0, -18.0, 0, 1}, {8.0, -18.0, 0, 1}, {9.0, -18.0, 0, 1}, {10.0, -18.0, 0, 1},
{11.0, -18.0, 0, 1}, {12.0, -18.0, 0, 1}, {13.0, -18.0, 0, 1}, {14.0, -18.0, 0, 1}, {15.0, -18.0, 0, 1}, {16.0, -18.0, 0, 1},
{17.0, -18.0, 0, 1}, {18.0, -18.0, 0, 1}, {19.0, -18.0, 0, 1}, {20.0, -18.0, 0, 1}, {-21.0, -17.0, 0, 1}, {-20.0, -17.0, 0, 1},
{-19.0, -17.0, 0, 1}, {-18.0, -17.0, 0, 1}, {17.0, -17.0, 0, 1}, {18.0, -17.0, 0, 1}, {19.0, -17.0, 0, 1}, {20.0, -17.0, 0, 1},
{-21.0, -16.0, 0, 1}, {-20.0, -16.0, 0, 1}, {-19.0, -16.0, 0, 1}, {-18.0, -16.0, 0, 1}, {17.0, -16.0, 0, 1}, {18.0, -16.0, 0, 1},
{19.0, -16.0, 0, 1}, {20.0, -16.0, 0, 1}, {-21.0, -15.0, 0, 1}, {-20.0, -15.0, 0, 1}, {-19.0, -15.0, 0, 1}, {-18.0, -15.0, 0, 1},
{17.0, -15.0, 0, 1}, {18.0, -15.0, 0, 1}, {19.0, -15.0, 0, 1}, {20.0, -15.0, 0, 1}, {-21.0, -14.0, 0, 1}, {-20.0, -14.0, 0, 1},
{-19.0, -14.0, 0, 1}, {-18.0, -14.0, 0, 1}, {17.0, -14.0, 0, 1}, {18.0, -14.0, 0, 1}, {19.0, -14.0, 0, 1}, {20.0, -14.0, 0, 1},
{-31.0, -13.0, 0, 1}, {-30.0, -13.0, 0, 1}, {-29.0, -13.0, 0, 1}, {-28.0, -13.0, 0, 1}, {-27.0, -13.0, 0, 1}, {-26.0, -13.0, 0, 1},
{-25.0, -13.0, 0, 1}, {-24.0, -13.0, 0, 1}, {-23.0, -13.0, 0, 1}, {-22.0, -13.0, 0, 1}, {-21.0, -13.0, 0, 1}, {-20.0, -13.0, 0, 1},
{-19.0, -13.0, 0, 1}, {-18.0, -13.0, 0, 1}, {17.0, -13.0, 0, 1}, {18.0, -13.0, 0, 1}, {19.0, -13.0, 0, 1}, {20.0, -13.0, 0, 1},
{21.0, -13.0, 0, 1}, {22.0, -13.0, 0, 1}, {23.0, -13.0, 0, 1}, {24.0, -13.0, 0, 1}, {25.0, -13.0, 0, 1}, {26.0, -13.0, 0, 1},
{27.0, -13.0, 0, 1}, {28.0, -13.0, 0, 1}, {29.0, -13.0, 0, 1}, {30.0, -13.0, 0, 1}, {-32.0, -12.0, 0, 1}, {-31.0, -12.0, 0, 1},
{-30.0, -12.0, 0, 1}, {-29.0, -12.0, 0, 1}, {-28.0, -12.0, 0, 1}, {-27.0, -12.0, 0, 1}, {-26.0, -12.0, 0, 1}, {-25.0, -12.0, 0, 1},
{-24.0, -12.0, 0, 1}, {-23.0, -12.0, 0, 1}, {-22.0, -12.0, 0, 1}, {-21.0, -12.0, 0, 1}, {-20.0, -12.0, 0, 1}, {-19.0, -12.0, 0, 1},
{-18.0, -12.0, 0, 1}, {-12.0, -12.0, 0, 1}, {-11.0, -12.0, 0, 1}, {-10.0, -12.0, 0, 1}, {-9.0, -12.0, 0, 1}, {-8.0, -12.0, 0, 1},
{-7.0, -12.0, 0, 1}, {-6.0, -12.0, 0, 1}, {-5.0, -12.0, 0, 1}, {-4.0, -12.0, 0, 1}, {-3.0, -12.0, 0, 1}, {-2.0, -12.0, 0, 1},
{-1.0, -12.0, 0, 1}, {0.0, -12.0, 0, 1}, {1.0, -12.0, 0, 1}, {2.0, -12.0, 0, 1}, {3.0, -12.0, 0, 1}, {4.0, -12.0, 0, 1},
{5.0, -12.0, 0, 1}, {6.0, -12.0, 0, 1}, {7.0, -12.0, 0, 1}, {8.0, -12.0, 0, 1}, {9.0, -12.0, 0, 1}, {10.0, -12.0, 0, 1},
{11.0, -12.0, 0, 1}, {17.0, -12.0, 0, 1}, {18.0, -12.0, 0, 1}, {19.0, -12.0, 0, 1}, {20.0, -12.0, 0, 1}, {21.0, -12.0, 0, 1},
{22.0, -12.0, 0, 1}, {23.0, -12.0, 0, 1}, {24.0, -12.0, 0, 1}, {25.0, -12.0, 0, 1}, {26.0, -12.0, 0, 1}, {27.0, -12.0, 0, 1},
{28.0, -12.0, 0, 1}, {29.0, -12.0, 0, 1}, {30.0, -12.0, 0, 1}, {31.0, -12.0, 0, 1}, {-32.0, -11.0, 0, 1}, {-31.0, -11.0, 0, 1},
{-30.0, -11.0, 0, 1}, {-29.0, -11.0, 0, 1}, {-28.0, -11.0, 0, 1}, {-27.0, -11.0, 0, 1}, {-26.0, -11.0, 0, 1}, {-25.0, -11.0, 0, 1},
{-24.0, -11.0, 0, 1}, {-23.0, -11.0, 0, 1}, {-22.0, -11.0, 0, 1}, {-21.0, -11.0, 0, 1}, {-20.0, -11.0, 0, 1}, {-19.0, -11.0, 0, 1},
{-18.0, -11.0, 0, 1}, {-12.0, -11.0, 0, 1}, {-11.0, -11.0, 0, 1}, {-10.0, -11.0, 0, 1}, {-9.0, -11.0, 0, 1}, {-8.0, -11.0, 0, 1},
{-7.0, -11.0, 0, 1}, {-6.0, -11.0, 0, 1}, {-5.0, -11.0, 0, 1}, {-4.0, -11.0, 0, 1}, {-3.0, -11.0, 0, 1}, {-2.0, -11.0, 0, 1},
{-1.0, -11.0, 0, 1}, {0.0, -11.0, 0, 1}, {1.0, -11.0, 0, 1}, {2.0, -11.0, 0, 1}, {3.0, -11.0, 0, 1}, {4.0, -11.0, 0, 1},
{5.0, -11.0, 0, 1}, {6.0, -11.0, 0, 1}, {7.0, -11.0, 0, 1}, {8.0, -11.0, 0, 1}, {9.0, -11.0, 0, 1}, {10.0, -11.0, 0, 1},
{11.0, -11.0, 0, 1}, {17.0, -11.0, 0, 1}, {18.0, -11.0, 0, 1}, {19.0, -11.0, 0, 1}, {20.0, -11.0, 0, 1}, {21.0, -11.0, 0, 1},
{22.0, -11.0, 0, 1}, {23.0, -11.0, 0, 1}, {24.0, -11.0, 0, 1}, {25.0, -11.0, 0, 1}, {26.0, -11.0, 0, 1}, {27.0, -11.0, 0, 1},
{28.0, -11.0, 0, 1}, {29.0, -11.0, 0, 1}, {30.0, -11.0, 0, 1}, {31.0, -11.0, 0, 1}, {-32.0, -10.0, 0, 1}, {-31.0, -10.0, 0, 1},
{-30.0, -10.0, 0, 1}, {-29.0, -10.0, 0, 1}, {-28.0, -10.0, 0, 1}, {-27.0, -10.0, 0, 1}, {-26.0, -10.0, 0, 1}, {-25.0, -10.0, 0, 1},
{-24.0, -10.0, 0, 1}, {-23.0, -10.0, 0, 1}, {-22.0, -10.0, 0, 1}, {-21.0, -10.0, 0, 1}, {-20.0, -10.0, 0, 1}, {-19.0, -10.0, 0, 1},
{-18.0, -10.0, 0, 1}, {-12.0, -10.0, 0, 1}, {-11.0, -10.0, 0, 1}, {-10.0, -10.0, 0, 1}, {-9.0, -10.0, 0, 1}, {-8.0, -10.0, 0, 1},
{-7.0, -10.0, 0, 1}, {-6.0, -10.0, 0, 1}, {-5.0, -10.0, 0, 1}, {-4.0, -10.0, 0, 1}, {-3.0, -10.0, 0, 1}, {-2.0, -10.0, 0, 1},
{-1.0, -10.0, 0, 1}, {0.0, -10.0, 0, 1}, {1.0, -10.0, 0, 1}, {2.0, -10.0, 0, 1}, {3.0, -10.0, 0, 1}, {4.0, -10.0, 0, 1},
{5.0, -10.0, 0, 1}, {6.0, -10.0, 0, 1}, {7.0, -10.0, 0, 1}, {8.0, -10.0, 0, 1}, {9.0, -10.0, 0, 1}, {10.0, -10.0, 0, 1},
{11.0, -10.0, 0, 1}, {17.0, -10.0, 0, 1}, {18.0, -10.0, 0, 1}, {19.0, -10.0, 0, 1}, {20.0, -10.0, 0, 1}, {21.0, -10.0, 0, 1},
{22.0, -10.0, 0, 1}, {23.0, -10.0, 0, 1}, {24.0, -10.0, 0, 1}, {25.0, -10.0, 0, 1}, {26.0, -10.0, 0, 1}, {27.0, -10.0, 0, 1},
{28.0, -10.0, 0, 1}, {29.0, -10.0, 0, 1}, {30.0, -10.0, 0, 1}, {31.0, -10.0, 0, 1}, {-21.0, -9.0, 0, 1}, {-20.0, -9.0, 0, 1},
{-19.0, -9.0, 0, 1}, {-18.0, -9.0, 0, 1}, {-12.0, -9.0, 0, 1}, {-11.0, -9.0, 0, 1}, {-10.0, -9.0, 0, 1}, {-9.0, -9.0, 0, 1},
{-8.0, -9.0, 0, 1}, {-7.0, -9.0, 0, 1}, {-6.0, -9.0, 0, 1}, {-5.0, -9.0, 0, 1}, {-4.0, -9.0, 0, 1}, {-3.0, -9.0, 0, 1},
{-2.0, -9.0, 0, 1}, {-1.0, -9.0, 0, 1}, {0.0, -9.0, 0, 1}, {1.0, -9.0, 0, 1}, {2.0, -9.0, 0, 1}, {3.0, -9.0, 0, 1},
{4.0, -9.0, 0, 1}, {5.0, -9.0, 0, 1}, {6.0, -9.0, 0, 1}, {7.0, -9.0, 0, 1}, {8.0, -9.0, 0, 1}, {9.0, -9.0, 0, 1},
{10.0, -9.0, 0, 1}, {11.0, -9.0, 0, 1}, {17.0, -9.0, 0, 1}, {18.0, -9.0, 0, 1}, {19.0, -9.0, 0, 1}, {20.0, -9.0, 0, 1},
{-21.0, -8.0, 0, 1}, {-20.0, -8.0, 0, 1}, {-19.0, -8.0, 0, 1}, {-18.0, -8.0, 0, 1}, {-12.0, -8.0, 0, 1}, {-11.0, -8.0, 0, 1},
{-10.0, -8.0, 0, 1}, {-9.0, -8.0, 0, 1}, {8.0, -8.0, 0, 1}, {9.0, -8.0, 0, 1}, {10.0, -8.0, 0, 1}, {11.0, -8.0, 0, 1},
{17.0, -8.0, 0, 1}, {18.0, -8.0, 0, 1}, {19.0, -8.0, 0, 1}, {20.0, -8.0, 0, 1}, {-21.0, -7.0, 0, 1}, {-20.0, -7.0, 0, 1},
{-19.0, -7.0, 0, 1}, {-18.0, -7.0, 0, 1}, {-12.0, -7.0, 0, 1}, {-11.0, -7.0, 0, 1}, {-10.0, -7.0, 0, 1}, {-9.0, -7.0, 0, 1},
{8.0, -7.0, 0, 1}, {9.0, -7.0, 0, 1}, {10.0, -7.0, 0, 1}, {11.0, -7.0, 0, 1}, {17.0, -7.0, 0, 1}, {18.0, -7.0, 0, 1},
{19.0, -7.0, 0, 1}, {20.0, -7.0, 0, 1}, {-31.0, -6.0, 0, 1}, {-30.0, -6.0, 0, 1}, {-29.0, -6.0, 0, 1}, {-28.0, -6.0, 0, 1},
{-27.0, -6.0, 0, 1}, {-26.0, -6.0, 0, 1}, {-25.0, -6.0, 0, 1}, {-24.0, -6.0, 0, 1}, {-23.0, -6.0, 0, 1}, {-22.0, -6.0, 0, 1},
{-21.0, -6.0, 0, 1}, {-20.0, -6.0, 0, 1}, {-19.0, -6.0, 0, 1}, {-18.0, -6.0, 0, 1}, {-12.0, -6.0, 0, 1}, {-11.0, -6.0, 0, 1},
{-10.0, -6.0, 0, 1}, {-9.0, -6.0, 0, 1}, {8.0, -6.0, 0, 1}, {9.0, -6.0, 0, 1}, {10.0, -6.0, 0, 1}, {11.0, -6.0, 0, 1},
{17.0, -6.0, 0, 1}, {18.0, -6.0, 0, 1}, {19.0, -6.0, 0, 1}, {20.0, -6.0, 0, 1}, {21.0, -6.0, 0, 1}, {22.0, -6.0, 0, 1},
{23.0, -6.0, 0, 1}, {24.0, -6.0, 0, 1}, {25.0, -6.0, 0, 1}, {26.0, -6.0, 0, 1}, {27.0, -6.0, 0, 1}, {28.0, -6.0, 0, 1},
{29.0, -6.0, 0, 1}, {30.0, -6.0, 0, 1}, {-32.0, -5.0, 0, 1}, {-31.0, -5.0, 0, 1}, {-30.0, -5.0, 0, 1}, {-29.0, -5.0, 0, 1},
{-28.0, -5.0, 0, 1}, {-27.0, -5.0, 0, 1}, {-26.0, -5.0, 0, 1}, {-25.0, -5.0, 0, 1}, {-24.0, -5.0, 0, 1}, {-23.0, -5.0, 0, 1},
{-22.0, -5.0, 0, 1}, {-21.0, -5.0, 0, 1}, {-20.0, -5.0, 0, 1}, {-19.0, -5.0, 0, 1}, {-18.0, -5.0, 0, 1}, {-12.0, -5.0, 0, 1},
{-11.0, -5.0, 0, 1}, {-10.0, -5.0, 0, 1}, {-9.0, -5.0, 0, 1}, {8.0, -5.0, 0, 1}, {9.0, -5.0, 0, 1}, {10.0, -5.0, 0, 1},
{11.0, -5.0, 0, 1}, {17.0, -5.0, 0, 1}, {18.0, -5.0, 0, 1}, {19.0, -5.0, 0, 1}, {20.0, -5.0, 0, 1}, {21.0, -5.0, 0, 1},
{22.0, -5.0, 0, 1}, {23.0, -5.0, 0, 1}, {24.0, -5.0, 0, 1}, {25.0, -5.0, 0, 1}, {26.0, -5.0, 0, 1}, {27.0, -5.0, 0, 1},
{28.0, -5.0, 0, 1}, {29.0, -5.0, 0, 1}, {30.0, -5.0, 0, 1}, {31.0, -5.0, 0, 1}, {-32.0, -4.0, 0, 1}, {-31.0, -4.0, 0, 1},
{-30.0, -4.0, 0, 1}, {-29.0, -4.0, 0, 1}, {-28.0, -4.0, 0, 1}, {-27.0, -4.0, 0, 1}, {-26.0, -4.0, 0, 1}, {-25.0, -4.0, 0, 1},
{-24.0, -4.0, 0, 1}, {-23.0, -4.0, 0, 1}, {-22.0, -4.0, 0, 1}, {-21.0, -4.0, 0, 1}, {-20.0, -4.0, 0, 1}, {-19.0, -4.0, 0, 1},
{-18.0, -4.0, 0, 1}, {-12.0, -4.0, 0, 1}, {-11.0, -4.0, 0, 1}, {-10.0, -4.0, 0, 1}, {-9.0, -4.0, 0, 1}, {8.0, -4.0, 0, 1},
{9.0, -4.0, 0, 1}, {10.0, -4.0, 0, 1}, {11.0, -4.0, 0, 1}, {17.0, -4.0, 0, 1}, {18.0, -4.0, 0, 1}, {19.0, -4.0, 0, 1},
{20.0, -4.0, 0, 1}, {21.0, -4.0, 0, 1}, {22.0, -4.0, 0, 1}, {23.0, -4.0, 0, 1}, {24.0, -4.0, 0, 1}, {25.0, -4.0, 0, 1},
{26.0, -4.0, 0, 1}, {27.0, -4.0, 0, 1}, {28.0, -4.0, 0, 1}, {29.0, -4.0, 0, 1}, {30.0, -4.0, 0, 1}, {31.0, -4.0, 0, 1},
{-32.0, -3.0, 0, 1}, {-31.0, -3.0, 0, 1}, {-30.0, -3.0, 0, 1}, {-29.0, -3.0, 0, 1}, {-28.0, -3.0, 0, 1}, {-27.0, -3.0, 0, 1},
{-26.0, -3.0, 0, 1}, {-25.0, -3.0, 0, 1}, {-24.0, -3.0, 0, 1}, {-23.0, -3.0, 0, 1}, {-22.0, -3.0, 0, 1}, {-21.0, -3.0, 0, 1},
{-20.0, -3.0, 0, 1}, {-19.0, -3.0, 0, 1}, {-18.0, -3.0, 0, 1}, {-12.0, -3.0, 0, 1}, {-11.0, -3.0, 0, 1}, {-10.0, -3.0, 0, 1},
{-9.0, -3.0, 0, 1}, {8.0, -3.0, 0, 1}, {9.0, -3.0, 0, 1}, {10.0, -3.0, 0, 1}, {11.0, -3.0, 0, 1}, {17.0, -3.0, 0, 1},
{18.0, -3.0, 0, 1}, {19.0, -3.0, 0, 1}, {20.0, -3.0, 0, 1}, {21.0, -3.0, 0, 1}, {22.0, -3.0, 0, 1}, {23.0, -3.0, 0, 1},
{24.0, -3.0, 0, 1}, {25.0, -3.0, 0, 1}, {26.0, -3.0, 0, 1}, {27.0, -3.0, 0, 1}, {28.0, -3.0, 0, 1}, {29.0, -3.0, 0, 1},
{30.0, -3.0, 0, 1}, {31.0, -3.0, 0, 1}, {-31.0, -2.0, 0, 1}, {-30.0, -2.0, 0, 1}, {-29.0, -2.0, 0, 1}, {-28.0, -2.0, 0, 1},
{-27.0, -2.0, 0, 1}, {-26.0, -2.0, 0, 1}, {-25.0, -2.0, 0, 1}, {-24.0, -2.0, 0, 1}, {-23.0, -2.0, 0, 1}, {-22.0, -2.0, 0, 1},
{-21.0, -2.0, 0, 1}, {-20.0, -2.0, 0, 1}, {-19.0, -2.0, 0, 1}, {-18.0, -2.0, 0, 1}, {-12.0, -2.0, 0, 1}, {-11.0, -2.0, 0, 1},
{-10.0, -2.0, 0, 1}, {-9.0, -2.0, 0, 1}, {8.0, -2.0, 0, 1}, {9.0, -2.0, 0, 1}, {10.0, -2.0, 0, 1}, {11.0, -2.0, 0, 1},
{17.0, -2.0, 0, 1}, {18.0, -2.0, 0, 1}, {19.0, -2.0, 0, 1}, {20.0, -2.0, 0, 1}, {21.0, -2.0, 0, 1}, {22.0, -2.0, 0, 1},
{23.0, -2.0, 0, 1}, {24.0, -2.0, 0, 1}, {25.0, -2.0, 0, 1}, {26.0, -2.0, 0, 1}, {27.0, -2.0, 0, 1}, {28.0, -2.0, 0, 1},
{29.0, -2.0, 0, 1}, {-21.0, -1.0, 0, 1}, {-20.0, -1.0, 0, 1}, {-19.0, -1.0, 0, 1}, {-18.0, -1.0, 0, 1}, {-12.0, -1.0, 0, 1},
{-11.0, -1.0, 0, 1}, {-10.0, -1.0, 0, 1}, {-9.0, -1.0, 0, 1}, {8.0, -1.0, 0, 1}, {9.0, -1.0, 0, 1}, {10.0, -1.0, 0, 1},
{11.0, -1.0, 0, 1}, {17.0, -1.0, 0, 1}, {18.0, -1.0, 0, 1}, {19.0, -1.0, 0, 1}, {20.0, -1.0, 0, 1}, {-21.0, 0.0, 0, 1},
{-20.0, 0.0, 0, 1}, {-19.0, 0.0, 0, 1}, {-18.0, 0.0, 0, 1}, {-12.0, 0.0, 0, 1}, {-11.0, 0.0, 0, 1}, {-10.0, 0.0, 0, 1},
{-9.0, 0.0, 0, 1}, {8.0, 0.0, 0, 1}, {9.0, 0.0, 0, 1}, {10.0, 0.0, 0, 1}, {11.0, 0.0, 0, 1}, {17.0, 0.0, 0, 1},
{18.0, 0.0, 0, 1}, {19.0, 0.0, 0, 1}, {20.0, 0.0, 0, 1}, {-31.0, 1.0, 0, 1}, {-30.0, 1.0, 0, 1}, {-29.0, 1.0, 0, 1},
{-28.0, 1.0, 0, 1}, {-27.0, 1.0, 0, 1}, {-26.0, 1.0, 0, 1}, {-25.0, 1.0, 0, 1}, {-24.0, 1.0, 0, 1}, {-23.0, 1.0, 0, 1},
{-22.0, 1.0, 0, 1}, {-21.0, 1.0, 0, 1}, {-20.0, 1.0, 0, 1}, {-19.0, 1.0, 0, 1}, {-18.0, 1.0, 0, 1}, {-12.0, 1.0, 0, 1},
{-11.0, 1.0, 0, 1}, {-10.0, 1.0, 0, 1}, {-9.0, 1.0, 0, 1}, {8.0, 1.0, 0, 1}, {9.0, 1.0, 0, 1}, {10.0, 1.0, 0, 1},
{11.0, 1.0, 0, 1}, {17.0, 1.0, 0, 1}, {18.0, 1.0, 0, 1}, {19.0, 1.0, 0, 1}, {20.0, 1.0, 0, 1}, {21.0, 1.0, 0, 1},
{22.0, 1.0, 0, 1}, {23.0, 1.0, 0, 1}, {24.0, 1.0, 0, 1}, {25.0, 1.0, 0, 1}, {26.0, 1.0, 0, 1}, {27.0, 1.0, 0, 1},
{28.0, 1.0, 0, 1}, {29.0, 1.0, 0, 1}, {30.0, 1.0, 0, 1}, {-32.0, 2.0, 0, 1}, {-31.0, 2.0, 0, 1}, {-30.0, 2.0, 0, 1},
{-29.0, 2.0, 0, 1}, {-28.0, 2.0, 0, 1}, {-27.0, 2.0, 0, 1}, {-26.0, 2.0, 0, 1}, {-25.0, 2.0, 0, 1}, {-24.0, 2.0, 0, 1},
{-23.0, 2.0, 0, 1}, {-22.0, 2.0, 0, 1}, {-21.0, 2.0, 0, 1}, {-20.0, 2.0, 0, 1}, {-19.0, 2.0, 0, 1}, {-18.0, 2.0, 0, 1},
{-12.0, 2.0, 0, 1}, {-11.0, 2.0, 0, 1}, {-10.0, 2.0, 0, 1}, {-9.0, 2.0, 0, 1}, {8.0, 2.0, 0, 1}, {9.0, 2.0, 0, 1},
{10.0, 2.0, 0, 1}, {11.0, 2.0, 0, 1}, {17.0, 2.0, 0, 1}, {18.0, 2.0, 0, 1}, {19.0, 2.0, 0, 1}, {20.0, 2.0, 0, 1},
{21.0, 2.0, 0, 1}, {22.0, 2.0, 0, 1}, {23.0, 2.0, 0, 1}, {24.0, 2.0, 0, 1}, {25.0, 2.0, 0, 1}, {26.0, 2.0, 0, 1},
{27.0, 2.0, 0, 1}, {28.0, 2.0, 0, 1}, {29.0, 2.0, 0, 1}, {30.0, 2.0, 0, 1}, {31.0, 2.0, 0, 1}, {-32.0, 3.0, 0, 1},
{-31.0, 3.0, 0, 1}, {-30.0, 3.0, 0, 1}, {-29.0, 3.0, 0, 1}, {-28.0, 3.0, 0, 1}, {-27.0, 3.0, 0, 1}, {-26.0, 3.0, 0, 1},
{-25.0, 3.0, 0, 1}, {-24.0, 3.0, 0, 1}, {-23.0, 3.0, 0, 1}, {-22.0, 3.0, 0, 1}, {-21.0, 3.0, 0, 1}, {-20.0, 3.0, 0, 1},
{-19.0, 3.0, 0, 1}, {-18.0, 3.0, 0, 1}, {-12.0, 3.0, 0, 1}, {-11.0, 3.0, 0, 1}, {-10.0, 3.0, 0, 1}, {-9.0, 3.0, 0, 1},
{8.0, 3.0, 0, 1}, {9.0, 3.0, 0, 1}, {10.0, 3.0, 0, 1}, {11.0, 3.0, 0, 1}, {17.0, 3.0, 0, 1}, {18.0, 3.0, 0, 1},
{19.0, 3.0, 0, 1}, {20.0, 3.0, 0, 1}, {21.0, 3.0, 0, 1}, {22.0, 3.0, 0, 1}, {23.0, 3.0, 0, 1}, {24.0, 3.0, 0, 1},
{25.0, 3.0, 0, 1}, {26.0, 3.0, 0, 1}, {27.0, 3.0, 0, 1}, {28.0, 3.0, 0, 1}, {29.0, 3.0, 0, 1}, {30.0, 3.0, 0, 1},
{31.0, 3.0, 0, 1}, {-32.0, 4.0, 0, 1}, {-31.0, 4.0, 0, 1}, {-30.0, 4.0, 0, 1}, {-29.0, 4.0, 0, 1}, {-28.0, 4.0, 0, 1},
{-27.0, 4.0, 0, 1}, {-26.0, 4.0, 0, 1}, {-25.0, 4.0, 0, 1}, {-24.0, 4.0, 0, 1}, {-23.0, 4.0, 0, 1}, {-22.0, 4.0, 0, 1},
{-21.0, 4.0, 0, 1}, {-20.0, 4.0, 0, 1}, {-19.0, 4.0, 0, 1}, {-18.0, 4.0, 0, 1}, {-12.0, 4.0, 0, 1}, {-11.0, 4.0, 0, 1},
{-10.0, 4.0, 0, 1}, {-9.0, 4.0, 0, 1}, {8.0, 4.0, 0, 1}, {9.0, 4.0, 0, 1}, {10.0, 4.0, 0, 1}, {11.0, 4.0, 0, 1},
{17.0, 4.0, 0, 1}, {18.0, 4.0, 0, 1}, {19.0, 4.0, 0, 1}, {20.0, 4.0, 0, 1}, {21.0, 4.0, 0, 1}, {22.0, 4.0, 0, 1},
{23.0, 4.0, 0, 1}, {24.0, 4.0, 0, 1}, {25.0, 4.0, 0, 1}, {26.0, 4.0, 0, 1}, {27.0, 4.0, 0, 1}, {28.0, 4.0, 0, 1},
{29.0, 4.0, 0, 1}, {30.0, 4.0, 0, 1}, {31.0, 4.0, 0, 1}, {-31.0, 5.0, 0, 1}, {-30.0, 5.0, 0, 1}, {-29.0, 5.0, 0, 1},
{-28.0, 5.0, 0, 1}, {-27.0, 5.0, 0, 1}, {-26.0, 5.0, 0, 1}, {-25.0, 5.0, 0, 1}, {-24.0, 5.0, 0, 1}, {-23.0, 5.0, 0, 1},
{-22.0, 5.0, 0, 1}, {-21.0, 5.0, 0, 1}, {-20.0, 5.0, 0, 1}, {-19.0, 5.0, 0, 1}, {-18.0, 5.0, 0, 1}, {-12.0, 5.0, 0, 1},
{-11.0, 5.0, 0, 1}, {-10.0, 5.0, 0, 1}, {-9.0, 5.0, 0, 1}, {8.0, 5.0, 0, 1}, {9.0, 5.0, 0, 1}, {10.0, 5.0, 0, 1},
{11.0, 5.0, 0, 1}, {17.0, 5.0, 0, 1}, {18.0, 5.0, 0, 1}, {19.0, 5.0, 0, 1}, {20.0, 5.0, 0, 1}, {21.0, 5.0, 0, 1},
{22.0, 5.0, 0, 1}, {23.0, 5.0, 0, 1}, {24.0, 5.0, 0, 1}, {25.0, 5.0, 0, 1}, {26.0, 5.0, 0, 1}, {27.0, 5.0, 0, 1},
{28.0, 5.0, 0, 1}, {29.0, 5.0, 0, 1}, {30.0, 5.0, 0, 1}, {-21.0, 6.0, 0, 1}, {-20.0, 6.0, 0, 1}, {-19.0, 6.0, 0, 1},
{-18.0, 6.0, 0, 1}, {-12.0, 6.0, 0, 1}, {-11.0, 6.0, 0, 1}, {-10.0, 6.0, 0, 1}, {-9.0, 6.0, 0, 1}, {8.0, 6.0, 0, 1},
{9.0, 6.0, 0, 1}, {10.0, 6.0, 0, 1}, {11.0, 6.0, 0, 1}, {17.0, 6.0, 0, 1}, {18.0, 6.0, 0, 1}, {19.0, 6.0, 0, 1},
{20.0, 6.0, 0, 1}, {-21.0, 7.0, 0, 1}, {-20.0, 7.0, 0, 1}, {-19.0, 7.0, 0, 1}, {-18.0, 7.0, 0, 1}, {-12.0, 7.0, 0, 1},
{-11.0, 7.0, 0, 1}, {-10.0, 7.0, 0, 1}, {-9.0, 7.0, 0, 1}, {8.0, 7.0, 0, 1}, {9.0, 7.0, 0, 1}, {10.0, 7.0, 0, 1},
{11.0, 7.0, 0, 1}, {17.0, 7.0, 0, 1}, {18.0, 7.0, 0, 1}, {19.0, 7.0, 0, 1}, {20.0, 7.0, 0, 1}, {-31.0, 8.0, 0, 1},
{-30.0, 8.0, 0, 1}, {-29.0, 8.0, 0, 1}, {-28.0, 8.0, 0, 1}, {-27.0, 8.0, 0, 1}, {-26.0, 8.0, 0, 1}, {-25.0, 8.0, 0, 1},
{-24.0, 8.0, 0, 1}, {-23.0, 8.0, 0, 1}, {-22.0, 8.0, 0, 1}, {-21.0, 8.0, 0, 1}, {-20.0, 8.0, 0, 1}, {-19.0, 8.0, 0, 1},
{-18.0, 8.0, 0, 1}, {-12.0, 8.0, 0, 1}, {-11.0, 8.0, 0, 1}, {-10.0, 8.0, 0, 1}, {-9.0, 8.0, 0, 1}, {-8.0, 8.0, 0, 1},
{-7.0, 8.0, 0, 1}, {-6.0, 8.0, 0, 1}, {-5.0, 8.0, 0, 1}, {-4.0, 8.0, 0, 1}, {-3.0, 8.0, 0, 1}, {-2.0, 8.0, 0, 1},
{-1.0, 8.0, 0, 1}, {0.0, 8.0, 0, 1}, {1.0, 8.0, 0, 1}, {2.0, 8.0, 0, 1}, {3.0, 8.0, 0, 1}, {4.0, 8.0, 0, 1},
{5.0, 8.0, 0, 1}, {6.0, 8.0, 0, 1}, {7.0, 8.0, 0, 1}, {8.0, 8.0, 0, 1}, {9.0, 8.0, 0, 1}, {10.0, 8.0, 0, 1},
{11.0, 8.0, 0, 1}, {17.0, 8.0, 0, 1}, {18.0, 8.0, 0, 1}, {19.0, 8.0, 0, 1}, {20.0, 8.0, 0, 1}, {21.0, 8.0, 0, 1},
{22.0, 8.0, 0, 1}, {23.0, 8.0, 0, 1}, {24.0, 8.0, 0, 1}, {25.0, 8.0, 0, 1}, {26.0, 8.0, 0, 1}, {27.0, 8.0, 0, 1},
{28.0, 8.0, 0, 1}, {29.0, 8.0, 0, 1}, {-32.0, 9.0, 0, 1}, {-31.0, 9.0, 0, 1}, {-30.0, 9.0, 0, 1}, {-29.0, 9.0, 0, 1},
{-28.0, 9.0, 0, 1}, {-27.0, 9.0, 0, 1}, {-26.0, 9.0, 0, 1}, {-25.0, 9.0, 0, 1}, {-24.0, 9.0, 0, 1}, {-23.0, 9.0, 0, 1},
{-22.0, 9.0, 0, 1}, {-21.0, 9.0, 0, 1}, {-20.0, 9.0, 0, 1}, {-19.0, 9.0, 0, 1}, {-18.0, 9.0, 0, 1}, {-12.0, 9.0, 0, 1},
{-11.0, 9.0, 0, 1}, {-10.0, 9.0, 0, 1}, {-9.0, 9.0, 0, 1}, {-8.0, 9.0, 0, 1}, {-7.0, 9.0, 0, 1}, {-6.0, 9.0, 0, 1},
{-5.0, 9.0, 0, 1}, {-4.0, 9.0, 0, 1}, {-3.0, 9.0, 0, 1}, {-2.0, 9.0, 0, 1}, {-1.0, 9.0, 0, 1}, {0.0, 9.0, 0, 1},
{1.0, 9.0, 0, 1}, {2.0, 9.0, 0, 1}, {3.0, 9.0, 0, 1}, {4.0, 9.0, 0, 1}, {5.0, 9.0, 0, 1}, {6.0, 9.0, 0, 1},
{7.0, 9.0, 0, 1}, {8.0, 9.0, 0, 1}, {9.0, 9.0, 0, 1}, {10.0, 9.0, 0, 1}, {11.0, 9.0, 0, 1}, {17.0, 9.0, 0, 1},
{18.0, 9.0, 0, 1}, {19.0, 9.0, 0, 1}, {20.0, 9.0, 0, 1}, {21.0, 9.0, 0, 1}, {22.0, 9.0, 0, 1}, {23.0, 9.0, 0, 1},
{24.0, 9.0, 0, 1}, {25.0, 9.0, 0, 1}, {26.0, 9.0, 0, 1}, {27.0, 9.0, 0, 1}, {28.0, 9.0, 0, 1}, {29.0, 9.0, 0, 1},
{30.0, 9.0, 0, 1}, {31.0, 9.0, 0, 1}, {-32.0, 10.0, 0, 1}, {-31.0, 10.0, 0, 1}, {-30.0, 10.0, 0, 1}, {-29.0, 10.0, 0, 1},
{-28.0, 10.0, 0, 1}, {-27.0, 10.0, 0, 1}, {-26.0, 10.0, 0, 1}, {-25.0, 10.0, 0, 1}, {-24.0, 10.0, 0, 1}, {-23.0, 10.0, 0, 1},
{-22.0, 10.0, 0, 1}, {-21.0, 10.0, 0, 1}, {-20.0, 10.0, 0, 1}, {-19.0, 10.0, 0, 1}, {-18.0, 10.0, 0, 1}, {-12.0, 10.0, 0, 1},
{-11.0, 10.0, 0, 1}, {-10.0, 10.0, 0, 1}, {-9.0, 10.0, 0, 1}, {-8.0, 10.0, 0, 1}, {-7.0, 10.0, 0, 1}, {-6.0, 10.0, 0, 1},
{-5.0, 10.0, 0, 1}, {-4.0, 10.0, 0, 1}, {-3.0, 10.0, 0, 1}, {-2.0, 10.0, 0, 1}, {-1.0, 10.0, 0, 1}, {0.0, 10.0, 0, 1},
{1.0, 10.0, 0, 1}, {2.0, 10.0, 0, 1}, {3.0, 10.0, 0, 1}, {4.0, 10.0, 0, 1}, {5.0, 10.0, 0, 1}, {6.0, 10.0, 0, 1},
{7.0, 10.0, 0, 1}, {8.0, 10.0, 0, 1}, {9.0, 10.0, 0, 1}, {10.0, 10.0, 0, 1}, {11.0, 10.0, 0, 1}, {17.0, 10.0, 0, 1},
{18.0, 10.0, 0, 1}, {19.0, 10.0, 0, 1}, {20.0, 10.0, 0, 1}, {21.0, 10.0, 0, 1}, {22.0, 10.0, 0, 1}, {23.0, 10.0, 0, 1},
{24.0, 10.0, 0, 1}, {25.0, 10.0, 0, 1}, {26.0, 10.0, 0, 1}, {27.0, 10.0, 0, 1}, {28.0, 10.0, 0, 1}, {29.0, 10.0, 0, 1},
{30.0, 10.0, 0, 1}, {31.0, 10.0, 0, 1}, {-32.0, 11.0, 0, 1}, {-31.0, 11.0, 0, 1}, {-30.0, 11.0, 0, 1}, {-29.0, 11.0, 0, 1},
{-28.0, 11.0, 0, 1}, {-27.0, 11.0, 0, 1}, {-26.0, 11.0, 0, 1}, {-25.0, 11.0, 0, 1}, {-24.0, 11.0, 0, 1}, {-23.0, 11.0, 0, 1},
{-22.0, 11.0, 0, 1}, {-21.0, 11.0, 0, 1}, {-20.0, 11.0, 0, 1}, {-19.0, 11.0, 0, 1}, {-18.0, 11.0, 0, 1}, {-12.0, 11.0, 0, 1},
{-11.0, 11.0, 0, 1}, {-10.0, 11.0, 0, 1}, {-9.0, 11.0, 0, 1}, {-8.0, 11.0, 0, 1}, {-7.0, 11.0, 0, 1}, {-6.0, 11.0, 0, 1},
{-5.0, 11.0, 0, 1}, {-4.0, 11.0, 0, 1}, {-3.0, 11.0, 0, 1}, {-2.0, 11.0, 0, 1}, {-1.0, 11.0, 0, 1}, {0.0, 11.0, 0, 1},
{1.0, 11.0, 0, 1}, {2.0, 11.0, 0, 1}, {3.0, 11.0, 0, 1}, {4.0, 11.0, 0, 1}, {5.0, 11.0, 0, 1}, {6.0, 11.0, 0, 1},
{7.0, 11.0, 0, 1}, {8.0, 11.0, 0, 1}, {9.0, 11.0, 0, 1}, {10.0, 11.0, 0, 1}, {11.0, 11.0, 0, 1}, {17.0, 11.0, 0, 1},
{18.0, 11.0, 0, 1}, {19.0, 11.0, 0, 1}, {20.0, 11.0, 0, 1}, {21.0, 11.0, 0, 1}, {22.0, 11.0, 0, 1}, {23.0, 11.0, 0, 1},
{24.0, 11.0, 0, 1}, {25.0, 11.0, 0, 1}, {26.0, 11.0, 0, 1}, {27.0, 11.0, 0, 1}, {28.0, 11.0, 0, 1}, {29.0, 11.0, 0, 1},
{30.0, 11.0, 0, 1}, {31.0, 11.0, 0, 1}, {-31.0, 12.0, 0, 1}, {-30.0, 12.0, 0, 1}, {-29.0, 12.0, 0, 1}, {-28.0, 12.0, 0, 1},
{-27.0, 12.0, 0, 1}, {-26.0, 12.0, 0, 1}, {-25.0, 12.0, 0, 1}, {-24.0, 12.0, 0, 1}, {-23.0, 12.0, 0, 1}, {-22.0, 12.0, 0, 1},
{-21.0, 12.0, 0, 1}, {-20.0, 12.0, 0, 1}, {-19.0, 12.0, 0, 1}, {-18.0, 12.0, 0, 1}, {17.0, 12.0, 0, 1}, {18.0, 12.0, 0, 1},
{19.0, 12.0, 0, 1}, {20.0, 12.0, 0, 1}, {21.0, 12.0, 0, 1}, {22.0, 12.0, 0, 1}, {23.0, 12.0, 0, 1}, {24.0, 12.0, 0, 1},
{25.0, 12.0, 0, 1}, {26.0, 12.0, 0, 1}, {27.0, 12.0, 0, 1}, {28.0, 12.0, 0, 1}, {29.0, 12.0, 0, 1}, {30.0, 12.0, 0, 1},
{-21.0, 13.0, 0, 1}, {-20.0, 13.0, 0, 1}, {-19.0, 13.0, 0, 1}, {-18.0, 13.0, 0, 1}, {17.0, 13.0, 0, 1}, {18.0, 13.0, 0, 1},
{19.0, 13.0, 0, 1}, {20.0, 13.0, 0, 1}, {-21.0, 14.0, 0, 1}, {-20.0, 14.0, 0, 1}, {-19.0, 14.0, 0, 1}, {-18.0, 14.0, 0, 1},
{17.0, 14.0, 0, 1}, {18.0, 14.0, 0, 1}, {19.0, 14.0, 0, 1}, {20.0, 14.0, 0, 1}, {-21.0, 15.0, 0, 1}, {-20.0, 15.0, 0, 1},
{-19.0, 15.0, 0, 1}, {-18.0, 15.0, 0, 1}, {17.0, 15.0, 0, 1}, {18.0, 15.0, 0, 1}, {19.0, 15.0, 0, 1}, {20.0, 15.0, 0, 1},
{-21.0, 16.0, 0, 1}, {-20.0, 16.0, 0, 1}, {-19.0, 16.0, 0, 1}, {-18.0, 16.0, 0, 1}, {17.0, 16.0, 0, 1}, {18.0, 16.0, 0, 1},
{19.0, 16.0, 0, 1}, {20.0, 16.0, 0, 1}, {-21.0, 17.0, 0, 1}, {-20.0, 17.0, 0, 1}, {-19.0, 17.0, 0, 1}, {-18.0, 17.0, 0, 1},
{-17.0, 17.0, 0, 1}, {-16.0, 17.0, 0, 1}, {-15.0, 17.0, 0, 1}, {-14.0, 17.0, 0, 1}, {-13.0, 17.0, 0, 1}, {-12.0, 17.0, 0, 1},
{-11.0, 17.0, 0, 1}, {-10.0, 17.0, 0, 1}, {-9.0, 17.0, 0, 1}, {-8.0, 17.0, 0, 1}, {-7.0, 17.0, 0, 1}, {-6.0, 17.0, 0, 1},
{-5.0, 17.0, 0, 1}, {-4.0, 17.0, 0, 1}, {-3.0, 17.0, 0, 1}, {-2.0, 17.0, 0, 1}, {-1.0, 17.0, 0, 1}, {0.0, 17.0, 0, 1},
{1.0, 17.0, 0, 1}, {2.0, 17.0, 0, 1}, {3.0, 17.0, 0, 1}, {4.0, 17.0, 0, 1}, {5.0, 17.0, 0, 1}, {6.0, 17.0, 0, 1},
{7.0, 17.0, 0, 1}, {8.0, 17.0, 0, 1}, {9.0, 17.0, 0, 1}, {10.0, 17.0, 0, 1}, {11.0, 17.0, 0, 1}, {12.0, 17.0, 0, 1},
{13.0, 17.0, 0, 1}, {14.0, 17.0, 0, 1}, {15.0, 17.0, 0, 1}, {16.0, 17.0, 0, 1}, {17.0, 17.0, 0, 1}, {18.0, 17.0, 0, 1},
{19.0, 17.0, 0, 1}, {20.0, 17.0, 0, 1}, {-21.0, 18.0, 0, 1}, {-20.0, 18.0, 0, 1}, {-19.0, 18.0, 0, 1}, {-18.0, 18.0, 0, 1},
{-17.0, 18.0, 0, 1}, {-16.0, 18.0, 0, 1}, {-15.0, 18.0, 0, 1}, {-14.0, 18.0, 0, 1}, {-13.0, 18.0, 0, 1}, {-12.0, 18.0, 0, 1},
{-11.0, 18.0, 0, 1}, {-10.0, 18.0, 0, 1}, {-9.0, 18.0, 0, 1}, {-8.0, 18.0, 0, 1}, {-7.0, 18.0, 0, 1}, {-6.0, 18.0, 0, 1},
{-5.0, 18.0, 0, 1}, {-4.0, 18.0, 0, 1}, {-3.0, 18.0, 0, 1}, {-2.0, 18.0, 0, 1}, {-1.0, 18.0, 0, 1}, {0.0, 18.0, 0, 1},
{1.0, 18.0, 0, 1}, {2.0, 18.0, 0, 1}, {3.0, 18.0, 0, 1}, {4.0, 18.0, 0, 1}, {5.0, 18.0, 0, 1}, {6.0, 18.0, 0, 1},
{7.0, 18.0, 0, 1}, {8.0, 18.0, 0, 1}, {9.0, 18.0, 0, 1}, {10.0, 18.0, 0, 1}, {11.0, 18.0, 0, 1}, {12.0, 18.0, 0, 1},
{13.0, 18.0, 0, 1}, {14.0, 18.0, 0, 1}, {15.0, 18.0, 0, 1}, {16.0, 18.0, 0, 1}, {17.0, 18.0, 0, 1}, {18.0, 18.0, 0, 1},
{19.0, 18.0, 0, 1}, {20.0, 18.0, 0, 1}, {-21.0, 19.0, 0, 1}, {-20.0, 19.0, 0, 1}, {-19.0, 19.0, 0, 1}, {-18.0, 19.0, 0, 1},
{-17.0, 19.0, 0, 1}, {-16.0, 19.0, 0, 1}, {-15.0, 19.0, 0, 1}, {-14.0, 19.0, 0, 1}, {-13.0, 19.0, 0, 1}, {-12.0, 19.0, 0, 1},
{-11.0, 19.0, 0, 1}, {-10.0, 19.0, 0, 1}, {-9.0, 19.0, 0, 1}, {-8.0, 19.0, 0, 1}, {-7.0, 19.0, 0, 1}, {-6.0, 19.0, 0, 1},
{-5.0, 19.0, 0, 1}, {-4.0, 19.0, 0, 1}, {-3.0, 19.0, 0, 1}, {-2.0, 19.0, 0, 1}, {-1.0, 19.0, 0, 1}, {0.0, 19.0, 0, 1},
{1.0, 19.0, 0, 1}, {2.0, 19.0, 0, 1}, {3.0, 19.0, 0, 1}, {4.0, 19.0, 0, 1}, {5.0, 19.0, 0, 1}, {6.0, 19.0, 0, 1},
{7.0, 19.0, 0, 1}, {8.0, 19.0, 0, 1}, {9.0, 19.0, 0, 1}, {10.0, 19.0, 0, 1}, {11.0, 19.0, 0, 1}, {12.0, 19.0, 0, 1},
{13.0, 19.0, 0, 1}, {14.0, 19.0, 0, 1}, {15.0, 19.0, 0, 1}, {16.0, 19.0, 0, 1}, {17.0, 19.0, 0, 1}, {18.0, 19.0, 0, 1},
{19.0, 19.0, 0, 1}, {20.0, 19.0, 0, 1}, {-21.0, 20.0, 0, 1}, {-20.0, 20.0, 0, 1}, {-19.0, 20.0, 0, 1}, {-18.0, 20.0, 0, 1},
{-17.0, 20.0, 0, 1}, {-16.0, 20.0, 0, 1}, {-15.0, 20.0, 0, 1}, {-14.0, 20.0, 0, 1}, {-13.0, 20.0, 0, 1}, {-12.0, 20.0, 0, 1},
{-11.0, 20.0, 0, 1}, {-10.0, 20.0, 0, 1}, {-9.0, 20.0, 0, 1}, {-8.0, 20.0, 0, 1}, {-7.0, 20.0, 0, 1}, {-6.0, 20.0, 0, 1},
{-5.0, 20.0, 0, 1}, {-4.0, 20.0, 0, 1}, {-3.0, 20.0, 0, 1}, {-2.0, 20.0, 0, 1}, {-1.0, 20.0, 0, 1}, {0.0, 20.0, 0, 1},
{1.0, 20.0, 0, 1}, {2.0, 20.0, 0, 1}, {3.0, 20.0, 0, 1}, {4.0, 20.0, 0, 1}, {5.0, 20.0, 0, 1}, {6.0, 20.0, 0, 1},
{7.0, 20.0, 0, 1}, {8.0, 20.0, 0, 1}, {9.0, 20.0, 0, 1}, {10.0, 20.0, 0, 1}, {11.0, 20.0, 0, 1}, {12.0, 20.0, 0, 1},
{13.0, 20.0, 0, 1}, {14.0, 20.0, 0, 1}, {15.0, 20.0, 0, 1}, {16.0, 20.0, 0, 1}, {17.0, 20.0, 0, 1}, {18.0, 20.0, 0, 1},
{19.0, 20.0, 0, 1}, {20.0, 20.0, 0, 1}, {-13.0, 21.0, 0, 1}, {-12.0, 21.0, 0, 1}, {-11.0, 21.0, 0, 1}, {-10.0, 21.0, 0, 1},
{-6.0, 21.0, 0, 1}, {-5.0, 21.0, 0, 1}, {-4.0, 21.0, 0, 1}, {-3.0, 21.0, 0, 1}, {-2.0, 21.0, 0, 1}, {1.0, 21.0, 0, 1},
{2.0, 21.0, 0, 1}, {3.0, 21.0, 0, 1}, {4.0, 21.0, 0, 1}, {5.0, 21.0, 0, 1}, {8.0, 21.0, 0, 1}, {9.0, 21.0, 0, 1},
{10.0, 21.0, 0, 1}, {11.0, 21.0, 0, 1}, {12.0, 21.0, 0, 1}, {-13.0, 22.0, 0, 1}, {-12.0, 22.0, 0, 1}, {-11.0, 22.0, 0, 1},
{-10.0, 22.0, 0, 1}, {-6.0, 22.0, 0, 1}, {-5.0, 22.0, 0, 1}, {-4.0, 22.0, 0, 1}, {-3.0, 22.0, 0, 1}, {-2.0, 22.0, 0, 1},
{1.0, 22.0, 0, 1}, {2.0, 22.0, 0, 1}, {3.0, 22.0, 0, 1}, {4.0, 22.0, 0, 1}, {5.0, 22.0, 0, 1}, {8.0, 22.0, 0, 1},
{9.0, 22.0, 0, 1}, {10.0, 22.0, 0, 1}, {11.0, 22.0, 0, 1}, {12.0, 22.0, 0, 1}, {-13.0, 23.0, 0, 1}, {-12.0, 23.0, 0, 1},
{-11.0, 23.0, 0, 1}, {-10.0, 23.0, 0, 1}, {-6.0, 23.0, 0, 1}, {-5.0, 23.0, 0, 1}, {-4.0, 23.0, 0, 1}, {-3.0, 23.0, 0, 1},
{-2.0, 23.0, 0, 1}, {1.0, 23.0, 0, 1}, {2.0, 23.0, 0, 1}, {3.0, 23.0, 0, 1}, {4.0, 23.0, 0, 1}, {5.0, 23.0, 0, 1},
{8.0, 23.0, 0, 1}, {9.0, 23.0, 0, 1}, {10.0, 23.0, 0, 1}, {11.0, 23.0, 0, 1}, {12.0, 23.0, 0, 1}, {-13.0, 24.0, 0, 1},
{-12.0, 24.0, 0, 1}, {-11.0, 24.0, 0, 1}, {-10.0, 24.0, 0, 1}, {-6.0, 24.0, 0, 1}, {-5.0, 24.0, 0, 1}, {-4.0, 24.0, 0, 1},
{-3.0, 24.0, 0, 1}, {-2.0, 24.0, 0, 1}, {1.0, 24.0, 0, 1}, {2.0, 24.0, 0, 1}, {3.0, 24.0, 0, 1}, {4.0, 24.0, 0, 1},
{5.0, 24.0, 0, 1}, {8.0, 24.0, 0, 1}, {9.0, 24.0, 0, 1}, {10.0, 24.0, 0, 1}, {11.0, 24.0, 0, 1}, {12.0, 24.0, 0, 1},
{-13.0, 25.0, 0, 1}, {-12.0, 25.0, 0, 1}, {-11.0, 25.0, 0, 1}, {-10.0, 25.0, 0, 1}, {-6.0, 25.0, 0, 1}, {-5.0, 25.0, 0, 1},
{-4.0, 25.0, 0, 1}, {-3.0, 25.0, 0, 1}, {-2.0, 25.0, 0, 1}, {1.0, 25.0, 0, 1}, {2.0, 25.0, 0, 1}, {3.0, 25.0, 0, 1},
{4.0, 25.0, 0, 1}, {5.0, 25.0, 0, 1}, {8.0, 25.0, 0, 1}, {9.0, 25.0, 0, 1}, {10.0, 25.0, 0, 1}, {11.0, 25.0, 0, 1},
{12.0, 25.0, 0, 1}, {-13.0, 26.0, 0, 1}, {-12.0, 26.0, 0, 1}, {-11.0, 26.0, 0, 1}, {-10.0, 26.0, 0, 1}, {-6.0, 26.0, 0, 1},
{-5.0, 26.0, 0, 1}, {-4.0, 26.0, 0, 1}, {-3.0, 26.0, 0, 1}, {-2.0, 26.0, 0, 1}, {1.0, 26.0, 0, 1}, {2.0, 26.0, 0, 1},
{3.0, 26.0, 0, 1}, {4.0, 26.0, 0, 1}, {5.0, 26.0, 0, 1}, {8.0, 26.0, 0, 1}, {9.0, 26.0, 0, 1}, {10.0, 26.0, 0, 1},
{11.0, 26.0, 0, 1}, {12.0, 26.0, 0, 1}, {-13.0, 27.0, 0, 1}, {-12.0, 27.0, 0, 1}, {-11.0, 27.0, 0, 1}, {-10.0, 27.0, 0, 1},
{-6.0, 27.0, 0, 1}, {-5.0, 27.0, 0, 1}, {-4.0, 27.0, 0, 1}, {-3.0, 27.0, 0, 1}, {-2.0, 27.0, 0, 1}, {1.0, 27.0, 0, 1},
{2.0, 27.0, 0, 1}, {3.0, 27.0, 0, 1}, {4.0, 27.0, 0, 1}, {5.0, 27.0, 0, 1}, {8.0, 27.0, 0, 1}, {9.0, 27.0, 0, 1},
{10.0, 27.0, 0, 1}, {11.0, 27.0, 0, 1}, {12.0, 27.0, 0, 1}, {-13.0, 28.0, 0, 1}, {-12.0, 28.0, 0, 1}, {-11.0, 28.0, 0, 1},
{-10.0, 28.0, 0, 1}, {-6.0, 28.0, 0, 1}, {-5.0, 28.0, 0, 1}, {-4.0, 28.0, 0, 1}, {-3.0, 28.0, 0, 1}, {-2.0, 28.0, 0, 1},
{1.0, 28.0, 0, 1}, {2.0, 28.0, 0, 1}, {3.0, 28.0, 0, 1}, {4.0, 28.0, 0, 1}, {5.0, 28.0, 0, 1}, {8.0, 28.0, 0, 1},
{9.0, 28.0, 0, 1}, {10.0, 28.0, 0, 1}, {11.0, 28.0, 0, 1}, {12.0, 28.0, 0, 1}, {-13.0, 29.0, 0, 1}, {-12.0, 29.0, 0, 1},
{-11.0, 29.0, 0, 1}, {-10.0, 29.0, 0, 1}, {-6.0, 29.0, 0, 1}, {-5.0, 29.0, 0, 1}, {-4.0, 29.0, 0, 1}, {-3.0, 29.0, 0, 1},
{-2.0, 29.0, 0, 1}, {1.0, 29.0, 0, 1}, {2.0, 29.0, 0, 1}, {3.0, 29.0, 0, 1}, {4.0, 29.0, 0, 1}, {5.0, 29.0, 0, 1},
{8.0, 29.0, 0, 1}, {9.0, 29.0, 0, 1}, {10.0, 29.0, 0, 1}, {11.0, 29.0, 0, 1}, {12.0, 29.0, 0, 1}, {-13.0, 30.0, 0, 1},
{-12.0, 30.0, 0, 1}, {-11.0, 30.0, 0, 1}, {-10.0, 30.0, 0, 1}, {-6.0, 30.0, 0, 1}, {-5.0, 30.0, 0, 1}, {-4.0, 30.0, 0, 1},
{-3.0, 30.0, 0, 1}, {1.0, 30.0, 0, 1}, {2.0, 30.0, 0, 1}, {3.0, 30.0, 0, 1}, {4.0, 30.0, 0, 1}, {5.0, 30.0, 0, 1},
{9.0, 30.0, 0, 1}, {10.0, 30.0, 0, 1}, {11.0, 30.0, 0, 1}, {12.0, 30.0, 0, 1}, {-12.0, 31.0, 0, 1}, {-11.0, 31.0, 0, 1},
{-10.0, 31.0, 0, 1}, {-5.0, 31.0, 0, 1}, {-4.0, 31.0, 0, 1}, {-3.0, 31.0, 0, 1}, {2.0, 31.0, 0, 1}, {3.0, 31.0, 0, 1},
{4.0, 31.0, 0, 1}, {9.0, 31.0, 0, 1}, {10.0, 31.0, 0, 1}, {11.0, 31.0, 0, 1}
};
#endif // CONFIG_3D_OBJECT_CUSTOM

View File

@@ -0,0 +1,18 @@
// File generated by ImgTo3D.py
// Image file converted to 3D matrix: cpu_logo.png
#pragma once
#include <stdint.h>
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
extern const uint8_t image_to_bmp_array_custom[512];
extern const float image_to_3d_matrix_custom[1732][4];
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,114 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <malloc.h>
#include <math.h>
#include "graphics_support.h"
void init_perspective_matrix(dspm::Mat &P_m)
{
const float fov = 90; // field of view in degrees
const float near = 0.0001;
const float far = 1;
const float S = 1 / (tan((fov / 2) * DEG_TO_RAD));
// Initialize matrix to zero
for (int row = 0; row < P_m.rows; row++) {
for (int col = 0; col < P_m.cols; col++) {
P_m(row, col) = 0;
}
}
P_m(0, 0) = S;
P_m(1, 1) = S;
P_m(2, 2) = -far / (far - near);
P_m(3, 2) = (-far * near) / (far - near);
P_m(2, 3) = -1;
P_m(3, 3) = 1;
}
void update_perspective_matrix(dspm::Mat &P_m, float fov)
{
const float near = 0.0001;
const float far = 1;
const float S = 1 / (tan((fov / 2) * DEG_TO_RAD));
// Initialize matrix to zero
for (int row = 0; row < P_m.rows; row++) {
for (int col = 0; col < P_m.cols; col++) {
P_m(row, col) = 0;
}
}
P_m(0, 0) = S;
P_m(1, 1) = S;
P_m(2, 2) = -far / (far - near);
P_m(3, 2) = (-far * near) / (far - near);
P_m(2, 3) = -1;
P_m(3, 3) = 1;
P_m(3, 0) = (float)SSD1606_X_CENTER;
P_m(3, 1) = (float)SSD1606_Y_CENTER;
}
void update_scaling_matrix(dspm::Mat &T_m, bool keep_diagonal, float scale_x, float scale_y, float scale_z)
{
if (keep_diagonal) { // Multiply the diagonal values of the transformation matrix with the scaling
T_m(0, 0) *= scale_x; // (in case a rotation is already applied)
T_m(1, 1) *= scale_y;
T_m(2, 2) *= scale_z;
} else {
T_m(0, 0) = scale_x;
T_m(1, 1) = scale_y;
T_m(2, 2) = scale_z;
}
}
void update_translation_matrix(dspm::Mat &T_m, bool row, float move_x, float move_y, float move_z)
{
if (row) { // update values in 4-th row, if translation matrix is the second multiplier
T_m(3, 0) = move_x;
T_m(3, 1) = move_y;
T_m(3, 2) = move_z;
} else { // update values in 4-th collum, if translation matrix is the first multiplier
T_m(0, 3) = move_x;
T_m(1, 3) = move_y;
T_m(2, 3) = move_z;
}
}
void update_rotation_matrix(dspm::Mat &T_m, float rot_x, float rot_y, float rot_z)
{
dspm::Mat rotation_data(3, 1); // matrix(3x1) that holds x, y, z rotation data
rotation_data(0, 0) = DEG_TO_RAD * rot_x; // rotation data x
rotation_data(1, 0) = DEG_TO_RAD * rot_y; // rotation data y
rotation_data(2, 0) = DEG_TO_RAD * rot_z; // rotation data z
// Create and populate rotation matrix R(3x3). Then inverse it
dspm::Mat R = ekf::eul2rotm(rotation_data.data).t();
// Enlarge rotation matrix from 3x3 to 4x4
for (int row = 0; row < R.rows; row++) { // Copy rotation matrix R(3x3) to transformation matrix T_m(4x4)
for (int col = 0; col < R.cols; col++) {
T_m(row, col) = R(row, col);
}
}
}
void print_matrix(dspm::Mat matrix)
{
for (int rows = 0; rows < matrix.rows; rows++) {
for (int cols = 0; cols < matrix.cols; cols++) {
std::cout << matrix(rows, cols) << ", \t";
}
std::cout << std::endl;
}
std::cout << std::endl << std::endl;
}

View File

@@ -0,0 +1,128 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_dsp.h"
#include "ekf_imu13states.h"
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#define DEG_TO_RAD 0.01745329252f // Degrees to radians conversion
#define RAD_TO_DEG 57.29577951f // Radians to degrees conversion
#define MATRIX_SIZE 4 // 4x4 matrices are used
#define SSD1306_WIDTH 128 // Display widh in pixels
#define SSD1306_HEIGHT 64 // DIsplay height
#define SSD1606_X_CENTER (SSD1306_WIDTH / 2) // Width center point
#define SSD1606_Y_CENTER (SSD1306_HEIGHT / 2) // Height center point
/**
* @brief Data struct of 3d image matrix
*
* This structure is used to hold a 3d coordinates of a monochromatic image centered to the origin of the
* cartesian space (0, 0, 0), that has ben processed by the image_to_3d_array.py.
*/
typedef struct image_3d_matrix_s {
const float (*matrix)[MATRIX_SIZE]; /*!< matrix holding xyz coordinates for each point of the converted image.*/
uint32_t matrix_len; /*!< image matrix length.*/
} image_3d_matrix_t;
/**
* @brief Data struct of 3d image matrix with kalman filter object
*
* This structure is used to hold a 3d coordinates of a monochromatic image centered to the origin of the
* cartesian space (0, 0, 0), that has ben processed by the image_to_3d_array.py.
* Kalman filter object is added to the matrix, for the purpose of RTOS task arguments.
*/
typedef struct image_3d_matrix_kalman_s {
const float (*matrix)[MATRIX_SIZE]; /*!< matrix holding xyz coordinates for each point of the converted image.*/
uint32_t matrix_len; /*!< image matrix length.*/
ekf_imu13states *ekf13; /*!< kalman filter object.*/
} image_3d_matrix_kalman_t;
/**
* @brief initialize perspective projection matrix
*
* Function initializes Mat class object holding perspective projection matrix.
*
* @param P_m: perspective projection matrix object from the Mat class
*/
void init_perspective_matrix(dspm::Mat &P_m);
/**
* @brief update scaling matrix
*
* Function updates scaling part of the transformation matrix.
*
* @param T_m: transformation matrix object from the Mat class
* @param keep_diagonal: if true: diagonal row of the transformation matrix T_m will be mulitplied with the scaling values
* if false: diagonal row of the transformation matrix T_m will be substituted with new scaling values
* @param scale_x: scaling value for x coordinate of the vector
* @param scale_y: scaling value for y coordinate of the vector
* @param scale_z: scaling value for z coordinate of the vector
*/
void update_scaling_matrix(dspm::Mat &T_m, bool keep_diagonal, float scale_x, float scale_y, float scale_z);
/**
* @brief update translation matrix
*
* Function updates translation part of the transformation matrix.
*
* @param T_m: transformation matrix object from the Mat class
* @param row: if true: translation values will be placed to the 3rd row of the transformation matrix T_m
* if false: translation values will be placed to the 3rd col of the transformation matrix T_m
* @param move_x: translation value for x coordinate of the vector
* @param move_y: translation value for y coordinate of the vector
* @param move_z: translation value for z coordinate of the vector
*/
void update_translation_matrix(dspm::Mat &T_m, bool row, float move_x, float move_y, float move_z);
/**
* @brief update rotation matrix
*
* Function updates rotation part of the tranformation matrix
*
* @param T_m: transformation matrix object from the Mat class
* @param rot_x: rotation angle for x direction of the vector
* @param rot_y: rotation angle for y direction of the vector
* @param rot_z: rotation angle for z direction of the vector
*/
void update_rotation_matrix(dspm::Mat &T_m, float rot_x, float rot_y, float rot_z);
/**
* @brief update perspective matrix
*
* Function updates perspective matrix with a new value of field of view
*
* @param P_m: perspective projection matrix object from the Mat class
* @param fov: field of view in degrees
*/
void update_perspective_matrix(dspm::Mat &P_m, float fov);
/**
* @brief printf matrix to the terminal output
*
* Print matrix for debug purposes
*
* @param matrix: matrix to be printed
*/
void print_matrix(dspm::Mat matrix);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,390 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import sys
import os
import subprocess
PIL_INSTALLED = True
PYTHON_FILE_NAME = os.path.basename(__file__) # name of the Python file itself
OUTPUT_FILE_NAME = "image_to_3d_matrix" # generated output .c and .h file names
OUTPUT_3D_MATRIX_NAME = "image_to_3d_matrix_custom" # generated output 3D matrix in the .c and .h file
OUTPUT_BMP_ARRAY_NAME = "image_to_bmp_array_custom" # generated output BMP array in the .c and .h file
TEMPLATE_FILE_NAME = "template_img_to_3d" # name of the .c and .h template files
ESP_IOT_AZURE_DISPLAY_WIDTH = 128 # ESP_IOT_AZURE board display width
ESP_IOT_AZURE_DISPLAY_HEIGHT = 64 # ESP_IOT_AZURE board display height
try:
from PIL import Image, ImageOps
except ImportError as e:
PIL_INSTALLED = False
print(e)
if not PIL_INSTALLED:
print("Installing Pillow package by running command -m pip install --upgrade Pillow")
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", "--upgrade", "Pillow"])
except subprocess.CalledProcessError as e:
print(e)
class Image3DMatrix:
""" class for 3d image matrix """
def __init__(self):
self.terminal_args = sys.argv # get command line arguments
self.img_path = None # path to the image
self.img_name = None # image name
self.img_ext = None # image extension
self.img_width = None # image target width
self.img_height = None # image target height
self.img_invert = False # invert monochromatic
self.img_include_bmp = False # include BMP form of the image
self.converted_img_dir = None # location to save the converted image
self.result_dir = None # location to save the .c and .h files
self.templates_dir = None # location where template files are saved
self.z_dist = 0 # Z distance of the 3D matrix
self.get_termianl_input()
def get_optional_args(self):
""" take optional arguments from the terminal, if there are any """
# take all the optional arguments
if len(self.terminal_args) > 4:
opt_args = self.terminal_args[4:len(self.terminal_args)]
# check the optional arguments "invert" "bmp" and z_dist
for arg in opt_args:
if arg.isdecimal():
self.z_dist = int(arg)
elif arg.lower() == "invert":
self.img_invert = True
elif arg.lower() == "bmp":
self.img_include_bmp = True
@staticmethod
def check_if_img_file_exists(path: str):
""" check, if provided image file path from terminal input is valid and an image file exits """
# check if a file exists on the provided absolute path
if os.path.isabs(path):
if not os.path.isfile(path):
print(f"Provided file {path} does not exist")
sys.exit()
# check if a file exists on the provided relative path
else:
absolute_path = os.path.join(os.getcwd(), path)
if not os.path.isfile(absolute_path):
print(f"Provided file {path} does not exist")
sys.exit()
else:
return absolute_path
return path
@staticmethod
def check_if_templates_exist():
""" Check if template .c and .h files exist """
# check if templates folder exists
templates_dir = os.path.join(os.getcwd(), "templates")
if not os.path.exists(templates_dir):
print(f"templates folder does not exist at location: {templates_dir}")
sys.exit()
# check if template .c file exists
template_c_file = os.path.join(templates_dir, f"{TEMPLATE_FILE_NAME}.c")
if not os.path.isfile(template_c_file):
print(f".c template file does not exist at location {template_c_file}")
sys.exit()
# check if template .h file exists
template_h_file = os.path.join(templates_dir, f"{TEMPLATE_FILE_NAME}.h")
if not os.path.isfile(template_h_file):
print(f".h template file does not exist at location {template_h_file}")
sys.exit()
return templates_dir
def get_img_name_extension(self):
""" extract image file name and image file extension """
img_file = os.path.basename(self.img_path) # image file with extension
self.img_name = os.path.splitext(img_file)[0] # extract file name
# Extract the file extension, to CAPS and remove the first character being dot
self.img_ext = os.path.splitext(img_file)[1].upper()[1:]
@staticmethod
def check_if_is_img(path: str, filename: str):
""" check if the provided file is an image and if its extension is supported """
# check if a file (which exits) is an image file
if not path.lower().endswith(('.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.gif')):
print(f"provided file {filename} is not a supported image file")
sys.exit()
@staticmethod
def check_pixels(height: str, width: str):
""" check if the provided result image height and width are decimal numbers """
# check if provided resulting image width and height are decimal numbers
if not height.isdecimal() and width.isdecimal():
print(f"Provided image target width {width} and/or height {height} not valid")
sys.exit()
@staticmethod
def check_if_pixels_in_range(height: int, width: int):
""" check if the provided result image height and width are in a valid range """
# check if the height and width are in the display's range
if (height > ESP_IOT_AZURE_DISPLAY_HEIGHT + 1 or width > ESP_IOT_AZURE_DISPLAY_WIDTH + 1 or
height < 1 or width < 1):
print(f"Provided image target width {width} and/or height {height} \
is out of range of the display's dimensions ({ESP_IOT_AZURE_DISPLAY_WIDTH}x{ESP_IOT_AZURE_DISPLAY_HEIGHT})")
sys.exit()
if height % 2 or width % 2:
print(f"Provided image target width {width} and height {height} must be even")
sys.exit()
def create_paths(self):
""" create paths for the result files """
# if running from the example folder, leave the results there
# if running from anywhere else, change cwd to dir, where the python is located
cwd = os.getcwd() # current working directory
abspath = os.path.abspath(__file__) # get the absolute path of the python script
python_dir = os.path.dirname(abspath) # get the absolute path of the folder, in which the python script is located
if os.path.join("img_to_3d_matrix", "example") not in cwd:
os.chdir(python_dir) # go to a directory where the python is located
# create an absolute path for the folder in which the image after conversion will be saved
self.converted_img_dir = os.path.join(os.getcwd(), "converted_image")
if not os.path.exists(self.converted_img_dir):
# if the path does not exist, create it
os.makedirs(self.converted_img_dir)
# create an absolute path for the folder, to which the resulting .c and .h files will be saved
self.result_dir = os.path.join(os.path.dirname(os.getcwd()), "3d_matrix", "3d_matrix_data")
if not os.path.exists(self.result_dir):
# if the path does not exist, use the current path instead
self.result_dir = os.getcwd()
if os.path.join("img_to_3d_matrix", "example") in cwd:
os.chdir(python_dir) # go to a directory where the python is located
def get_termianl_input(self):
""" get input parameters from terminal """
if ((len(self.terminal_args) == 2) and (str(self.terminal_args[1]) == "--help")):
query = '\n'.join([
f"\npython {PYTHON_FILE_NAME} -image_path -image_width -image_height -z_distance -invert -bmp\n\n"
"-image_path absolute or relative path to an image to be processed",
"-image_width width (in pixels) of the resulting 3D image",
"-image_height height (in pixels) of the resulting 3D image",
"-z_distance (optional) Z distance (in pixels) of the resulting 3D image, leave blank otherwise",
"-invert (optional) to invert colors, leave blank otherwise",
"-bmp (optional) to include BMP from of the provided image, leave blank otherwise"])
print(query)
sys.exit()
elif len(self.terminal_args) < 4:
print(f"Too few arguments run following command for help\npython {PYTHON_FILE_NAME} --help")
sys.exit()
else:
self.img_path = self.terminal_args[1]
self.img_width = self.terminal_args[2]
self.img_height = self.terminal_args[3]
self.get_optional_args()
self.img_path = self.check_if_img_file_exists(self.img_path)
self.get_img_name_extension()
self.check_if_is_img(self.img_path, self.img_name)
self.check_pixels(self.img_height, self.img_width)
self.img_height = int(self.img_height)
self.img_width = int(self.img_width)
self.check_if_pixels_in_range(self.img_height, self.img_width)
self.create_paths()
self.templates_dir = self.check_if_templates_exist()
def fromat_comas_spaces(element_index: int, array_len: int, elements_per_line: int, c_file):
""" Formating of the spaces, commas and new lines for arrays in the .c file """
# Dont put comma after the last array member
if element_index != array_len:
c_file.write(",")
# new line after each elements_per_line
if not element_index % elements_per_line:
c_file.write("\n")
# start a new line with tab
if element_index != array_len:
c_file.write(" ")
# put space after each coma
# except after the last array member and before a new line
else:
if element_index != array_len:
c_file.write(" ")
def ouptput_files_gen(img3d: Image3DMatrix, bmp_arr: list, matrix_arr: list):
""" write 3d matrix array and optional BMP array to .c and .h files """
# generate a c file and save it to the main folder (if exists in the file structure)
output_c_file_name = f"{OUTPUT_FILE_NAME}.c"
with open(os.path.join(img3d.templates_dir, f"{TEMPLATE_FILE_NAME}.c"), "r", encoding="utf8") as c_template_file:
with open(os.path.join(img3d.result_dir, output_c_file_name), "w+", encoding="utf8") as c_file:
c_file.write(f"// File generated by {PYTHON_FILE_NAME}\n") # write first line to c_file
c_file.write(f"// Image file converted to 3D matrix {img3d.img_name}.{img3d.img_ext.lower()}\n")
next(c_template_file)
next(c_template_file) # skip first 2 lines from c_template_file
for line in c_template_file:
if "const" in line:
# include BMP form if requested
if img3d.img_include_bmp:
c_file.write(f"const uint8_t {OUTPUT_BMP_ARRAY_NAME}[{len(bmp_arr)}] = {{\n\n ")
for index, bmp_byte in enumerate(bmp_arr, start=1):
c_file.write(f"0x{bmp_byte:02x}")
fromat_comas_spaces(index, len(bmp_arr), 16, c_file)
c_file.write("\n};\n\n")
# write 3d matrix form
c_file.write(f"const float {OUTPUT_3D_MATRIX_NAME}[{len(matrix_arr)}][4] = {{\n\n ")
for index, line in enumerate(matrix_arr, start=1):
line_joined = ', '.join(map(str, line))
c_file.write(f"{{{line_joined}}}")
fromat_comas_spaces(index, len(matrix_arr), 6, c_file)
c_file.write("\n};\n")
next(c_template_file)
continue
# copy line from c_template_file to c_file
c_file.write(line)
c_file.close()
c_template_file.close()
# generate an h file and save it to the main folder (if exists in the file structure)
output_h_file_name = f"{OUTPUT_FILE_NAME}.h"
with open(os.path.join(img3d.templates_dir, f"{TEMPLATE_FILE_NAME}.h"), "r", encoding="utf8") as h_template_file:
with open(os.path.join(img3d.result_dir, output_h_file_name), "w+", encoding="utf8") as h_file:
h_file.write(f"// File generated by {PYTHON_FILE_NAME}\n") # write first line to h_file
h_file.write(f"// Image file converted to 3D matrix: {img3d.img_name}.{img3d.img_ext.lower()}\n")
next(h_template_file)
next(h_template_file) # skip first 2 lines from h_template_file
for line in h_template_file:
if "extern const" in line:
# include BMP header if requested
if img3d.img_include_bmp:
h_file.write(f"extern const uint8_t {OUTPUT_BMP_ARRAY_NAME}[{len(bmp_arr)}];\n")
# include 3d matrix header
h_file.write(f"extern const float {OUTPUT_3D_MATRIX_NAME}[{len(matrix_arr)}][4];\n")
next(h_template_file)
continue
h_file.write(line)
h_file.close()
h_template_file.close()
query = '\n'.join([
"\nOutput files generation done!",
f"Output files {output_c_file_name} {output_h_file_name}",
f"Output files location {img3d.result_dir}"])
print(query)
def create_matrix(img3d: Image3DMatrix, pixels: list, bmp_img_array: list, matrix_img_array: list):
""" Create a 3D matrix and optional BMP form of the converted image """
multiplier = pow(2, 7)
byte = 0
# convert pixels to both, bmp and 3d from
for index, pixel in enumerate(pixels, start=1):
if pixel:
byte += multiplier
y_coord = int((index - 1) / img3d.img_width)
x_coord = (index - 1) - (y_coord * img3d.img_width) - (img3d.img_width / 2)
y_coord = y_coord - (img3d.img_height / 2)
matrix_img_array.append((x_coord, y_coord, img3d.z_dist, 1))
multiplier >>= 1
if not index % 8:
multiplier = pow(2, 7)
bmp_img_array.append(byte)
byte = 0
def convert_img(img3d: Image3DMatrix):
""" image conversion to list of monochromatic pixels """
# open an image and convert the image to monochromatic
img = Image.open(img3d.img_path)
img = img.convert(mode="1", dither=Image.NONE)
# if requested, invert black and white
if img3d.img_invert:
img = ImageOps.invert(img)
# resize the image and get the width and height of the resized image, to check
img = img.resize((int(img3d.img_width), int(img3d.img_height)), resample=Image.NEAREST)
res_width, res_height = img.size
# get image pixels as a list, after converting the image to monochromatic - pixels are either 0 or 255
pixels = list(img.getdata())
# check if the resized image has the same dimensions as the required dimensions
if (res_width, res_height) != (img3d.img_width, img3d.img_height):
query = '\n'.join([
"Image conversion was not successful!",
f"Required width and height: {img3d.img_width} {img3d.img_height}",
f"Real width and height: {res_width} {res_height}"])
print(query)
sys.exit()
else:
# if converted correctly, save the converted image
if img3d.img_invert:
invert = "_invert_conv."
else:
invert = "_conv."
converted_img_name = ''.join([img3d.img_name, invert, img3d.img_ext.lower()])
converted_img_location = os.path.join(img3d.converted_img_dir, converted_img_name)
img.save(converted_img_location, format=img3d.img_ext, subsampling=0, quality=100)
query = '\n'.join([
"Image conversion done!",
f"Converted image {converted_img_name}",
f"Converted image location {os.path.join(img3d.converted_img_dir)}"])
print(query)
return pixels
def main():
""" main function of the image_to_3d_matrix """
img3d = Image3DMatrix()
pixels = convert_img(img3d)
bmp_img_array = list()
matrix_img_array = list()
create_matrix(img3d, pixels, bmp_img_array, matrix_img_array)
ouptput_files_gen(img3d, bmp_img_array, matrix_img_array)
print("\nAll done!")
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,105 @@
# Getting the 3D matrix
`ImgTo3D.py` generates a 3D matrix for the monochromatic display, from a provided 2D graphics - image. As the output, `.c` and `.h` files containing the 3D matrix, are already included in the project structure, to `CMakeList.txt` and `.cpp` files. The output arrays are named `image_to_3d_matrix_custom` and `image_to_bmp_array_custom` by default. The converted image is saved for a preview.
The script can be called by following commands:
python ImgTo3D.py image_path image_width image_height
* `ImgTo3D.py` - absolute path to the python file
* `image_path` - absolute or relative path to the image, to be converted
* `image_width` - resulting width of the converted image (in pixels)
* `image_height` - resulting height of the converted image (in pixels)
The python script converts the provided image first to a monochromatic image, then resizes the image according to the provided dimensions, then converts the image to a 3D matrix and finally saves the 3D into a `.c` file.
python ImgTo3D.py --help
Run for help - prints hints, how to run the file and information about the arguments.
### Optional arguments
python ImgTo3D.py image_path image_width image_height z_dist invert bmp
* `z_dist` puts a distance (in pixels) into the Z direction of each matrix row - each 3D point. 0 is used otherwise
* `invert` inverts black and white in the converted monochromatic image, causing inverting pixels that will be lit on the display
* `bmp` includes a BMP form of the converted image into the output `.c` and `.h` files
The optional arguments can be added in any sequence.
# Example
To get example results, in the example folder, run the script from the example folder like so:
/example $ python ../ImgTo3D.py cpu_logo.png 64 64 invert bmp
To get the results already integrated into the project, run the script from any other location:
/any_location $ python abs_path/ImgTo3D.py cpu_logo.png 64 64 bmp invert
Converts `cpu_logo.png` image into a 3D matrix with dimensions of `64x64` pixels, with inverted colors and the BMP is included into the output file.
## Output files
python script produces the following output:
* `converted_image/cpu_logo_invert_conv.png` image after the conversion (monochromatic and resized image)
* `image_to_3d_matrix.c` c file with 3D and BMP matrices in `const` arrays
* `image_to_3d_matrix.h` h file with 3D and BMP arrays declarations in `extern const`
The output `.c` and `.h` files are based on template files `template_img_to_3d.c` and `template_img_to_3d.h`. From which, only the variables declarations are changed according to the converted image.
The expected output from the python script is the following:
Image conversion done!
Converted image cpu_logo_invert_conv.png
Converted image location ${workspaceFolder}/graphics/img_to_3d_matrix/example/converted_image
Output files generation done!
Output files image_to_3d_matrix.c image_to_3d_matrix.h
Output files location ${workspaceFolder}/graphics/img_to_3d_matrix/example
All done!
## Image conversion output example
<div align="center">
<table>
<tr>
<td style="height: 15px;">
<p align = "center">
Converted image (64x64)
</p>
</td>
<td style="height: 15px;">
<p align = "center">
Inverted colors (64x64)
</p>
</td>
</tr>
<tr>
<td>
<div align="center">
<img src= "converted_image/cpu_logo_conv.png">
</div>
</td>
<td>
<div align="center">
<img src= "converted_image/cpu_logo_invert_conv.png">
</div>
</td>
</tr>
<tr>
<td colspan="2" style="height: 15px;">
<p align = "center">
Original image (256x256)
</p>
</td>
</tr>
<tr>
<td colspan="2">
<div align="center">
<img src= "image/cpu_logo.png" style="width:50%">
</div>
</td>
</tr>
</table>
</div>

View File

@@ -0,0 +1,11 @@
// template file - template_img_to_3d.c
// arrays declarations will be modified by python script ImgTo3D.py
#include "image_to_3d_matrix.h"
#ifdef CONFIG_3D_OBJECT_CUSTOM
const uint8_t TEMPLATE_ARRAY_BMP_IMAGE[NUM_OF_BYTES] = {};
const float TEMPLATE_ARRAY_IMAGE_TO_3D_MATRIX[NUM_OF_POINTS][4] = {};
#endif // CONFIG_3D_OBJECT_CUSTOM

View File

@@ -0,0 +1,18 @@
// template file - template_img_to_3d.h
// arrays declarations will be modified by python script ImgTo3D.py
#pragma once
#include <stdint.h>
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
extern const uint8_t TEMPLATE_ARRAY_BMP_IMAGE[NUM_OF_BYTES];
extern const float TEMPLATE_ARRAY_IMAGE_TO_3D_MATRIX[NUM_OF_POINTS][4];
#ifdef __cplusplus
}
#endif