Skip to content
Snippets Groups Projects
Commit 1791d5cd authored by Mateusz Zalega's avatar Mateusz Zalega Committed by rahix
Browse files

fix(gfx): Fix Bresenham's line drawing algorithm implementation

parent d23fbdd0
No related branches found
No related tags found
No related merge requests found
#include "epicardium.h" #include "display.h"
#include "tmr_utils.h"
#include "gpio.h"
#include "Fonts/fonts.h" #include "Fonts/fonts.h"
#include "tmr.h"
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h"
#include "gfx.h"
#include "display.h"
#include "LCD_Driver.h" #include "LCD_Driver.h"
#include "epicardium.h"
#include "gfx.h"
#include "gpio.h"
#include "task.h"
#include "tmr.h"
#include "tmr_utils.h"
static TaskHandle_t lock = NULL; static TaskHandle_t lock = NULL;
...@@ -73,7 +73,7 @@ int epic_disp_line( ...@@ -73,7 +73,7 @@ int epic_disp_line(
return cl; return cl;
} else { } else {
/* TODO add linestyle support to gfx code */ /* TODO add linestyle support to gfx code */
gfx_thick_line( gfx_line(
&display_screen, &display_screen,
xstart, xstart,
ystart, ystart,
......
...@@ -3,31 +3,32 @@ ...@@ -3,31 +3,32 @@
******************************************************************************/ ******************************************************************************/
/***** Includes *****/ /***** Includes *****/
#include "mxc_config.h" #include "bhy_uc_driver.h"
#include "led.h"
#include "board.h" #include "board.h"
#include "tmr_utils.h" #include "display.h"
#include "gfx.h"
#include "gpio.h"
#include "i2c.h" #include "i2c.h"
#include "led.h"
#include "mxc_config.h"
#include "pmic.h"
#include "rtc.h" #include "rtc.h"
#include "spi.h" #include "spi.h"
#include "gpio.h" #include "tmr_utils.h"
#include "bhy_uc_driver.h"
#include "pmic.h"
#include "gfx.h"
#include "display.h"
#include "card10.h" #include "card10.h"
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#define M_PI 3.1415 #define M_PI 3.1415
/***** Definitions *****/ /***** Definitions *****/
/* should be greater or equal to 69 bytes, page size (50) + maximum packet size(18) + 1 */ /* should be greater or equal to 69 bytes, page size (50) + maximum packet
* size(18) + 1 */
#define FIFO_SIZE 300 #define FIFO_SIZE 300
#define ROTATION_VECTOR_SAMPLE_RATE 10 #define ROTATION_VECTOR_SAMPLE_RATE 10
#define MAX_PACKET_LENGTH 18 #define MAX_PACKET_LENGTH 18
...@@ -49,7 +50,7 @@ void draw_arrow(int angle, int color) ...@@ -49,7 +50,7 @@ void draw_arrow(int angle, int color)
int x2 = x1 - sin * 30; int x2 = x1 - sin * 30;
int y2 = y1 - cos * 30; int y2 = y1 - cos * 30;
gfx_thick_line(&display_screen, x1, y1, x2, y2, 2, color); gfx_line(&display_screen, x1, y1, x2, y2, 2, color);
sin = sinf((angle - 140) * 2 * M_PI / 360.); sin = sinf((angle - 140) * 2 * M_PI / 360.);
cos = cosf((angle - 140) * 2 * M_PI / 360.); cos = cosf((angle - 140) * 2 * M_PI / 360.);
...@@ -57,7 +58,7 @@ void draw_arrow(int angle, int color) ...@@ -57,7 +58,7 @@ void draw_arrow(int angle, int color)
int x3 = x2 - sin * 10; int x3 = x2 - sin * 10;
int y3 = y2 - cos * 10; int y3 = y2 - cos * 10;
gfx_thick_line(&display_screen, x2, y2, x3, y3, 2, color); gfx_line(&display_screen, x2, y2, x3, y3, 2, color);
sin = sinf((angle + 140) * 2 * M_PI / 360.); sin = sinf((angle + 140) * 2 * M_PI / 360.);
cos = cosf((angle + 140) * 2 * M_PI / 360.); cos = cosf((angle + 140) * 2 * M_PI / 360.);
...@@ -65,7 +66,7 @@ void draw_arrow(int angle, int color) ...@@ -65,7 +66,7 @@ void draw_arrow(int angle, int color)
int x4 = x2 - sin * 10; int x4 = x2 - sin * 10;
int y4 = y2 - cos * 10; int y4 = y2 - cos * 10;
gfx_thick_line(&display_screen, x2, y2, x4, y4, 2, color); gfx_line(&display_screen, x2, y2, x4, y4, 2, color);
} }
/***** Functions *****/ /***** Functions *****/
...@@ -92,8 +93,8 @@ static void sensors_callback_orientation( ...@@ -92,8 +93,8 @@ static void sensors_callback_orientation(
draw_arrow(sensor_data->data_vector.x * 360 / 32768, color); draw_arrow(sensor_data->data_vector.x * 360 / 32768, color);
char buf[128]; char buf[128];
//sprintf(buf, "Azimuth: %3d", angle); // sprintf(buf, "Azimuth: %3d", angle);
//Paint_DrawString_EN(0, 0, buf, &Font12, BLACK, color); // Paint_DrawString_EN(0, 0, buf, &Font12, BLACK, color);
sprintf(buf, "%3d", angle); sprintf(buf, "%3d", angle);
gfx_puts( gfx_puts(
...@@ -220,10 +221,14 @@ int main(void) ...@@ -220,10 +221,14 @@ int main(void)
} }
#endif #endif
//if(bhy_install_sensor_callback(VS_TYPE_GEOMAGNETIC_FIELD, VS_WAKEUP, sensors_callback_vector)) // if(bhy_install_sensor_callback(VS_TYPE_GEOMAGNETIC_FIELD, VS_WAKEUP,
//if(bhy_install_sensor_callback(VS_TYPE_GRAVITY, VS_WAKEUP, sensors_callback_vector)) // sensors_callback_vector))
//if(bhy_install_sensor_callback(VS_TYPE_ACCELEROMETER, VS_WAKEUP, sensors_callback_vector)) // if(bhy_install_sensor_callback(VS_TYPE_GRAVITY, VS_WAKEUP,
//if(bhy_install_sensor_callback(VS_TYPE_MAGNETIC_FIELD_UNCALIBRATED, VS_WAKEUP, sensors_callback_vector_uncalib)) // sensors_callback_vector))
// if(bhy_install_sensor_callback(VS_TYPE_ACCELEROMETER, VS_WAKEUP,
// sensors_callback_vector))
// if(bhy_install_sensor_callback(VS_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
// VS_WAKEUP, sensors_callback_vector_uncalib))
if (bhy_install_sensor_callback( if (bhy_install_sensor_callback(
VS_TYPE_ORIENTATION, VS_TYPE_ORIENTATION,
VS_WAKEUP, VS_WAKEUP,
...@@ -240,10 +245,14 @@ int main(void) ...@@ -240,10 +245,14 @@ int main(void)
#endif #endif
/* enables the virtual sensor */ /* enables the virtual sensor */
//if(bhy_enable_virtual_sensor(VS_TYPE_GEOMAGNETIC_FIELD, VS_WAKEUP, ROTATION_VECTOR_SAMPLE_RATE, 0, VS_FLUSH_NONE, 0, 0)) // if(bhy_enable_virtual_sensor(VS_TYPE_GEOMAGNETIC_FIELD, VS_WAKEUP,
//if(bhy_enable_virtual_sensor(VS_TYPE_GRAVITY, VS_WAKEUP, ROTATION_VECTOR_SAMPLE_RATE, 0, VS_FLUSH_NONE, 0, 0)) // ROTATION_VECTOR_SAMPLE_RATE, 0, VS_FLUSH_NONE, 0, 0))
//if(bhy_enable_virtual_sensor(VS_TYPE_ACCELEROMETER, VS_WAKEUP, ROTATION_VECTOR_SAMPLE_RATE, 0, VS_FLUSH_NONE, 0, 0)) // if(bhy_enable_virtual_sensor(VS_TYPE_GRAVITY, VS_WAKEUP,
//if(bhy_enable_virtual_sensor(VS_TYPE_MAGNETIC_FIELD_UNCALIBRATED, VS_WAKEUP, ROTATION_VECTOR_SAMPLE_RATE, 0, VS_FLUSH_NONE, 0, 0)) // ROTATION_VECTOR_SAMPLE_RATE, 0, VS_FLUSH_NONE, 0, 0))
// if(bhy_enable_virtual_sensor(VS_TYPE_ACCELEROMETER, VS_WAKEUP,
// ROTATION_VECTOR_SAMPLE_RATE, 0, VS_FLUSH_NONE, 0, 0))
// if(bhy_enable_virtual_sensor(VS_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
// VS_WAKEUP, ROTATION_VECTOR_SAMPLE_RATE, 0, VS_FLUSH_NONE, 0, 0))
if (bhy_enable_virtual_sensor( if (bhy_enable_virtual_sensor(
VS_TYPE_ORIENTATION, VS_TYPE_ORIENTATION,
VS_WAKEUP, VS_WAKEUP,
...@@ -288,8 +297,10 @@ int main(void) ...@@ -288,8 +297,10 @@ int main(void)
); );
} }
/* the logic here is that if doing a partial parsing of the fifo, then we should not parse */ /* the logic here is that if doing a partial parsing of the fifo, then we
/* the last 18 bytes (max length of a packet) so that we don't try to parse an incomplete */ * should not parse */
/* the last 18 bytes (max length of a packet) so that we don't try to
* parse an incomplete */
/* packet */ /* packet */
} while ((result == BHY_SUCCESS) && } while ((result == BHY_SUCCESS) &&
(bytes_read > (bytes_read >
......
...@@ -3,19 +3,19 @@ ...@@ -3,19 +3,19 @@
******************************************************************************/ ******************************************************************************/
/***** Includes *****/ /***** Includes *****/
#include "tmr_utils.h" #include "DEV_Config.h"
#include "gpio.h"
#include "gfx.h"
#include "display.h"
#include "Fonts/fonts.h" #include "Fonts/fonts.h"
#include "display.h"
#include "gfx.h"
#include "gpio.h"
#include "image/image.h" #include "image/image.h"
#include "tmr.h" #include "tmr.h"
#include "DEV_Config.h" #include "tmr_utils.h"
#include "card10.h" #include "card10.h"
#include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <string.h> #include <string.h>
// ***************************************************************************** // *****************************************************************************
...@@ -33,8 +33,8 @@ int main(void) ...@@ -33,8 +33,8 @@ int main(void)
gfx_puts(&Font24, &display_screen, 0, 0, "123", 0x000f, 0xfff8); gfx_puts(&Font24, &display_screen, 0, 0, "123", 0x000f, 0xfff8);
gfx_puts(&Font24, &display_screen, 23, 0, "ABC", 0x000f, 0xfff8); gfx_puts(&Font24, &display_screen, 23, 0, "ABC", 0x000f, 0xfff8);
gfx_rectangle(&display_screen, 70, 10, 100, 40, 2, red); gfx_rectangle(&display_screen, 70, 10, 100, 40, 2, red);
gfx_thick_line(&display_screen, 70, 10, 100, 40, 2, green); gfx_line(&display_screen, 70, 10, 100, 40, 2, green);
gfx_thick_line(&display_screen, 100, 10, 70, 40, 2, yellow); gfx_line(&display_screen, 100, 10, 70, 40, 2, yellow);
gfx_circle(&display_screen, 85, 25, 22, 2, green); gfx_circle(&display_screen, 85, 25, 22, 2, green);
gfx_copy_region_raw( gfx_copy_region_raw(
......
#include "gfx.h" #include "gfx.h"
#include "framebuffer.h" #include "framebuffer.h"
#include <math.h>
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
const struct gfx_color_rgb gfx_colors_rgb[COLORS] = { const struct gfx_color_rgb gfx_colors_rgb[COLORS] = {
{ 255, 255, 255 }, /* WHITE */ { 255, 255, 255 }, /* WHITE */
...@@ -157,17 +157,10 @@ void gfx_circle_fill(struct gfx_region *reg, int x, int y, int r, Color c) ...@@ -157,17 +157,10 @@ void gfx_circle_fill(struct gfx_region *reg, int x, int y, int r, Color c)
void gfx_rectangle( void gfx_rectangle(
struct gfx_region *reg, int x, int y, int w, int h, int t, Color c struct gfx_region *reg, int x, int y, int w, int h, int t, Color c
) { ) {
if (t > 1) { gfx_line(reg, x, y, x + w, y, t, c);
gfx_thick_line(reg, x, y, x + w, y, t, c); gfx_line(reg, x, y + h, x + w, y + h, t, c);
gfx_thick_line(reg, x, y + h, x + w, y + h, t, c); gfx_line(reg, x, y, x, y + h, t, c);
gfx_thick_line(reg, x, y, x, y + h, t, c); gfx_line(reg, x + w, y, x + w, y + h, t, c);
gfx_thick_line(reg, x + w, y, x + w, y + h, t, c);
} else {
gfx_line(reg, x, y, x + w, y, c);
gfx_line(reg, x, y + h, x + w, y + h, c);
gfx_line(reg, x, y, x, y + h, c);
gfx_line(reg, x + w, y, x + w, y + h, c);
}
} }
void gfx_rectangle_fill( void gfx_rectangle_fill(
...@@ -179,37 +172,86 @@ void gfx_rectangle_fill( ...@@ -179,37 +172,86 @@ void gfx_rectangle_fill(
} }
} }
void gfx_line(struct gfx_region *reg, int x1, int y1, int x2, int y2, Color c) /*
{ * For derivation of the algorithm, see:
float dx = x2 - x1; * https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
float dy = y2 - y1; */
float de = fabs(dy / dx); static void plot_line_low(
float e = .0f; struct gfx_region *reg, int x0, int y0, int x1, int y1, int t, Color c
int y = y1; ) {
for (int x = x1; x < x2; x++) { int dx = x1 - x0;
gfx_setpixel(reg, x, y, c); int dy = y1 - y0;
e += de; int yi = 1;
if (e >= .5f) {
y += dy >= .0f ? 1 : -1; if (dy < 0) {
e -= 1.0f; yi = -1;
dy = -dy;
}
int d = 2 * dy - dx;
int y = y0;
for (int x = x0; x < x1; x++) {
if (t > 1) {
gfx_circle_fill(reg, x, y, t, c);
} else {
gfx_setpixel(reg, x, y, c);
} }
if (d > 0) {
y += yi;
d -= 2 * dx;
}
d += 2 * dy;
} }
} }
void gfx_thick_line( /*
struct gfx_region *reg, int x1, int y1, int x2, int y2, int t, Color c * For derivation of the algorithm, see:
* https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
*/
static void plot_line_high(
struct gfx_region *reg, int x0, int y0, int x1, int y1, int t, Color c
) { ) {
float dx = x2 - x1; int dx = x1 - x0;
float dy = y2 - y1; int dy = y1 - y0;
float de = fabs(dy / dx); int xi = 1;
float e = .0f;
int y = y1; if (dx < 0) {
for (int x = x1; x < x2; x++) { xi = -1;
gfx_circle_fill(reg, x, y, t, c); dx = -dx;
e += de; }
if (e >= .5f) {
y += dy >= .0f ? 1 : -1; int d = 2 * dx - dy;
e -= 1.0f; int x = x0;
for (int y = y0; y < y1; y++) {
if (t > 1) {
gfx_circle_fill(reg, x, y, t, c);
} else {
gfx_setpixel(reg, x, y, c);
}
if (d > 0) {
x += xi;
d -= 2 * dy;
}
d += 2 * dx;
}
}
void gfx_line(
struct gfx_region *reg, int x0, int y0, int x1, int y1, int t, Color c
) {
if (abs(y1 - y0) < abs(x1 - x0)) {
if (x0 > x1) {
plot_line_low(reg, x1, y1, x0, y0, t, c);
} else {
plot_line_low(reg, x0, y0, x1, y1, t, c);
}
} else {
if (y0 > y1) {
plot_line_high(reg, x1, y1, x0, y0, t, c);
} else {
plot_line_high(reg, x0, y0, x1, y1, t, c);
} }
} }
} }
......
...@@ -28,9 +28,8 @@ void gfx_rectangle(struct gfx_region *reg, int x, int y, int w, int h, ...@@ -28,9 +28,8 @@ void gfx_rectangle(struct gfx_region *reg, int x, int y, int w, int h,
int t, Color c); int t, Color c);
void gfx_rectangle_fill(struct gfx_region *reg, int x, int y, int w, int h, void gfx_rectangle_fill(struct gfx_region *reg, int x, int y, int w, int h,
Color c); Color c);
void gfx_line(struct gfx_region *reg, int x1, int y1, int x2, int y2, Color c); void gfx_line(struct gfx_region *reg, int x1, int y1, int x2, int y2,
void gfx_thick_line(struct gfx_region *reg, int x1, int y1, int x2, int y2, int t, Color c);
int t, Color c);
void gfx_update(struct gfx_region *reg); void gfx_update(struct gfx_region *reg);
enum gfx_color { enum gfx_color {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment