Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/libs/lvgl/lv_draw/lv_draw_triangle.c
1476 views
1
/**
2
* @file lv_draw_triangle.c
3
*
4
*/
5
6
/*********************
7
* INCLUDES
8
*********************/
9
#include "lv_draw_triangle.h"
10
#include "../lv_misc/lv_math.h"
11
12
/*********************
13
* DEFINES
14
*********************/
15
16
/**********************
17
* TYPEDEFS
18
**********************/
19
20
/**********************
21
* STATIC PROTOTYPES
22
**********************/
23
24
/**********************
25
* STATIC VARIABLES
26
**********************/
27
static void point_swap(lv_point_t * p1, lv_point_t * p2);
28
29
/**********************
30
* MACROS
31
**********************/
32
33
/**********************
34
* GLOBAL FUNCTIONS
35
**********************/
36
#if USE_LV_TRIANGLE != 0
37
/**
38
*
39
* @param points pointer to an array with 3 points
40
* @param mask the triangle will be drawn only in this mask
41
* @param color color of the triangle
42
*/
43
void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask, lv_color_t color)
44
{
45
lv_point_t tri[3];
46
47
memcpy(tri, points, sizeof(tri));
48
49
/*Sort the vertices according to their y coordinate (0: y max, 1: y mid, 2:y min)*/
50
if(tri[1].y < tri[0].y) point_swap(&tri[1], &tri[0]);
51
if(tri[2].y < tri[1].y) point_swap(&tri[2], &tri[1]);
52
if(tri[1].y < tri[0].y) point_swap(&tri[1], &tri[0]);
53
54
/*Return is the triangle is degenerated*/
55
if(tri[0].x == tri[1].x && tri[0].y == tri[1].y) return;
56
if(tri[1].x == tri[2].x && tri[1].y == tri[2].y) return;
57
if(tri[0].x == tri[2].x && tri[0].y == tri[2].y) return;
58
59
if(tri[0].x == tri[1].x && tri[1].x == tri[2].x) return;
60
if(tri[0].y == tri[1].y && tri[1].y == tri[2].y) return;
61
62
/*Draw the triangle*/
63
lv_point_t edge1;
64
lv_coord_t dx1 = LV_MATH_ABS(tri[0].x - tri[1].x);
65
lv_coord_t sx1 = tri[0].x < tri[1].x ? 1 : -1;
66
lv_coord_t dy1 = LV_MATH_ABS(tri[0].y - tri[1].y);
67
lv_coord_t sy1 = tri[0].y < tri[1].y ? 1 : -1;
68
lv_coord_t err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;
69
lv_coord_t err_tmp1;
70
71
lv_point_t edge2;
72
lv_coord_t dx2 = LV_MATH_ABS(tri[0].x - tri[2].x);
73
lv_coord_t sx2 = tri[0].x < tri[2].x ? 1 : -1;
74
lv_coord_t dy2 = LV_MATH_ABS(tri[0].y - tri[2].y);
75
lv_coord_t sy2 = tri[0].y < tri[2].y ? 1 : -1;
76
lv_coord_t err2 = (dx1 > dy2 ? dx2 : -dy2) / 2;
77
lv_coord_t err_tmp2;
78
79
lv_coord_t y1_tmp;
80
lv_coord_t y2_tmp;
81
82
edge1.x = tri[0].x;
83
edge1.y = tri[0].y;
84
edge2.x = tri[0].x;
85
edge2.y = tri[0].y;
86
lv_area_t act_area;
87
lv_area_t draw_area;
88
89
while(1) {
90
act_area.x1 = edge1.x;
91
act_area.x2 = edge2.x ;
92
act_area.y1 = edge1.y;
93
act_area.y2 = edge2.y ;
94
95
96
draw_area.x1 = LV_MATH_MIN(act_area.x1, act_area.x2);
97
draw_area.x2 = LV_MATH_MAX(act_area.x1, act_area.x2);
98
draw_area.y1 = LV_MATH_MIN(act_area.y1, act_area.y2);
99
draw_area.y2 = LV_MATH_MAX(act_area.y1, act_area.y2);
100
draw_area.x2--; /*Do not draw most right pixel because it will be drawn by the adjacent triangle*/
101
fill_fp(&draw_area, mask, color, LV_OPA_50);
102
103
/*Calc. the next point of edge1*/
104
y1_tmp = edge1.y;
105
do {
106
if(edge1.x == tri[1].x && edge1.y == tri[1].y) {
107
108
dx1 = LV_MATH_ABS(tri[1].x - tri[2].x);
109
sx1 = tri[1].x < tri[2].x ? 1 : -1;
110
dy1 = LV_MATH_ABS(tri[1].y - tri[2].y);
111
sy1 = tri[1].y < tri[2].y ? 1 : -1;
112
err1 = (dx1 > dy1 ? dx1 : -dy1) / 2;
113
} else if(edge1.x == tri[2].x && edge1.y == tri[2].y) return;
114
err_tmp1 = err1;
115
if(err_tmp1 > -dx1) {
116
err1 -= dy1;
117
edge1.x += sx1;
118
}
119
if(err_tmp1 < dy1) {
120
err1 += dx1;
121
edge1.y += sy1;
122
}
123
} while(edge1.y == y1_tmp);
124
125
/*Calc. the next point of edge2*/
126
y2_tmp = edge2.y;
127
do {
128
if(edge2.x == tri[2].x && edge2.y == tri[2].y) return;
129
err_tmp2 = err2;
130
if(err_tmp2 > -dx2) {
131
err2 -= dy2;
132
edge2.x += sx2;
133
}
134
if(err_tmp2 < dy2) {
135
err2 += dx2;
136
edge2.y += sy2;
137
}
138
} while(edge2.y == y2_tmp);
139
}
140
}
141
#endif
142
143
/**********************
144
* STATIC FUNCTIONS
145
**********************/
146
147
148
#if USE_LV_TRIANGLE != 0
149
/**
150
* Swap two points
151
* p1 pointer to the first point
152
* p2 pointer to the second point
153
*/
154
static void point_swap(lv_point_t * p1, lv_point_t * p2)
155
{
156
lv_point_t tmp;
157
tmp.x = p1->x;
158
tmp.y = p1->y;
159
160
p1->x = p2->x;
161
p1->y = p2->y;
162
163
p2->x = tmp.x;
164
p2->y = tmp.y;
165
166
}
167
168
#endif
169
170