components/u8g2/csrc/u8g2_circle.c

changeset 0
88d965579617
equal deleted inserted replaced
-1:000000000000 0:88d965579617
1 /*
2
3 u8g2_circle.c
4
5 Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
6
7 Copyright (c) 2016, olikraus@gmail.com
8 All rights reserved.
9
10 Redistribution and use in source and binary forms, with or without modification,
11 are permitted provided that the following conditions are met:
12
13 * Redistributions of source code must retain the above copyright notice, this list
14 of conditions and the following disclaimer.
15
16 * Redistributions in binary form must reproduce the above copyright notice, this
17 list of conditions and the following disclaimer in the documentation and/or other
18 materials provided with the distribution.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
21 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
22 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34 */
35
36 #include "u8g2.h"
37
38 /*==============================================*/
39 /* Circle */
40
41 static void u8g2_draw_circle_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE;
42
43 static void u8g2_draw_circle_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option)
44 {
45 /* upper right */
46 if ( option & U8G2_DRAW_UPPER_RIGHT )
47 {
48 u8g2_DrawPixel(u8g2, x0 + x, y0 - y);
49 u8g2_DrawPixel(u8g2, x0 + y, y0 - x);
50 }
51
52 /* upper left */
53 if ( option & U8G2_DRAW_UPPER_LEFT )
54 {
55 u8g2_DrawPixel(u8g2, x0 - x, y0 - y);
56 u8g2_DrawPixel(u8g2, x0 - y, y0 - x);
57 }
58
59 /* lower right */
60 if ( option & U8G2_DRAW_LOWER_RIGHT )
61 {
62 u8g2_DrawPixel(u8g2, x0 + x, y0 + y);
63 u8g2_DrawPixel(u8g2, x0 + y, y0 + x);
64 }
65
66 /* lower left */
67 if ( option & U8G2_DRAW_LOWER_LEFT )
68 {
69 u8g2_DrawPixel(u8g2, x0 - x, y0 + y);
70 u8g2_DrawPixel(u8g2, x0 - y, y0 + x);
71 }
72 }
73
74 static void u8g2_draw_circle(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)
75 {
76 u8g2_int_t f;
77 u8g2_int_t ddF_x;
78 u8g2_int_t ddF_y;
79 u8g2_uint_t x;
80 u8g2_uint_t y;
81
82 f = 1;
83 f -= rad;
84 ddF_x = 1;
85 ddF_y = 0;
86 ddF_y -= rad;
87 ddF_y *= 2;
88 x = 0;
89 y = rad;
90
91 u8g2_draw_circle_section(u8g2, x, y, x0, y0, option);
92
93 while ( x < y )
94 {
95 if (f >= 0)
96 {
97 y--;
98 ddF_y += 2;
99 f += ddF_y;
100 }
101 x++;
102 ddF_x += 2;
103 f += ddF_x;
104
105 u8g2_draw_circle_section(u8g2, x, y, x0, y0, option);
106 }
107 }
108
109 void u8g2_DrawCircle(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)
110 {
111 /* check for bounding box */
112 #ifdef U8G2_WITH_INTERSECTION
113 {
114 if ( u8g2_IsIntersection(u8g2, x0-rad, y0-rad, x0+rad+1, y0+rad+1) == 0 )
115 return;
116 }
117 #endif /* U8G2_WITH_INTERSECTION */
118
119
120 /* draw circle */
121 u8g2_draw_circle(u8g2, x0, y0, rad, option);
122 }
123
124 /*==============================================*/
125 /* Disk */
126
127 static void u8g2_draw_disc_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE;
128
129 static void u8g2_draw_disc_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option)
130 {
131 /* upper right */
132 if ( option & U8G2_DRAW_UPPER_RIGHT )
133 {
134 u8g2_DrawVLine(u8g2, x0+x, y0-y, y+1);
135 u8g2_DrawVLine(u8g2, x0+y, y0-x, x+1);
136 }
137
138 /* upper left */
139 if ( option & U8G2_DRAW_UPPER_LEFT )
140 {
141 u8g2_DrawVLine(u8g2, x0-x, y0-y, y+1);
142 u8g2_DrawVLine(u8g2, x0-y, y0-x, x+1);
143 }
144
145 /* lower right */
146 if ( option & U8G2_DRAW_LOWER_RIGHT )
147 {
148 u8g2_DrawVLine(u8g2, x0+x, y0, y+1);
149 u8g2_DrawVLine(u8g2, x0+y, y0, x+1);
150 }
151
152 /* lower left */
153 if ( option & U8G2_DRAW_LOWER_LEFT )
154 {
155 u8g2_DrawVLine(u8g2, x0-x, y0, y+1);
156 u8g2_DrawVLine(u8g2, x0-y, y0, x+1);
157 }
158 }
159
160 static void u8g2_draw_disc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)
161 {
162 u8g2_int_t f;
163 u8g2_int_t ddF_x;
164 u8g2_int_t ddF_y;
165 u8g2_uint_t x;
166 u8g2_uint_t y;
167
168 f = 1;
169 f -= rad;
170 ddF_x = 1;
171 ddF_y = 0;
172 ddF_y -= rad;
173 ddF_y *= 2;
174 x = 0;
175 y = rad;
176
177 u8g2_draw_disc_section(u8g2, x, y, x0, y0, option);
178
179 while ( x < y )
180 {
181 if (f >= 0)
182 {
183 y--;
184 ddF_y += 2;
185 f += ddF_y;
186 }
187 x++;
188 ddF_x += 2;
189 f += ddF_x;
190
191 u8g2_draw_disc_section(u8g2, x, y, x0, y0, option);
192 }
193 }
194
195 void u8g2_DrawDisc(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rad, uint8_t option)
196 {
197 /* check for bounding box */
198 #ifdef U8G2_WITH_INTERSECTION
199 {
200 if ( u8g2_IsIntersection(u8g2, x0-rad, y0-rad, x0+rad+1, y0+rad+1) == 0 )
201 return;
202 }
203 #endif /* U8G2_WITH_INTERSECTION */
204
205 /* draw disc */
206 u8g2_draw_disc(u8g2, x0, y0, rad, option);
207 }
208
209 /*==============================================*/
210 /* Ellipse */
211
212 /*
213 Source:
214 Foley, Computer Graphics, p 90
215 */
216 static void u8g2_draw_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE;
217 static void u8g2_draw_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option)
218 {
219 /* upper right */
220 if ( option & U8G2_DRAW_UPPER_RIGHT )
221 {
222 u8g2_DrawPixel(u8g2, x0 + x, y0 - y);
223 }
224
225 /* upper left */
226 if ( option & U8G2_DRAW_UPPER_LEFT )
227 {
228 u8g2_DrawPixel(u8g2, x0 - x, y0 - y);
229 }
230
231 /* lower right */
232 if ( option & U8G2_DRAW_LOWER_RIGHT )
233 {
234 u8g2_DrawPixel(u8g2, x0 + x, y0 + y);
235 }
236
237 /* lower left */
238 if ( option & U8G2_DRAW_LOWER_LEFT )
239 {
240 u8g2_DrawPixel(u8g2, x0 - x, y0 + y);
241 }
242 }
243
244 static void u8g2_draw_ellipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option)
245 {
246 u8g2_uint_t x, y;
247 u8g2_long_t xchg, ychg;
248 u8g2_long_t err;
249 u8g2_long_t rxrx2;
250 u8g2_long_t ryry2;
251 u8g2_long_t stopx, stopy;
252
253 rxrx2 = rx;
254 rxrx2 *= rx;
255 rxrx2 *= 2;
256
257 ryry2 = ry;
258 ryry2 *= ry;
259 ryry2 *= 2;
260
261 x = rx;
262 y = 0;
263
264 xchg = 1;
265 xchg -= rx;
266 xchg -= rx;
267 xchg *= ry;
268 xchg *= ry;
269
270 ychg = rx;
271 ychg *= rx;
272
273 err = 0;
274
275 stopx = ryry2;
276 stopx *= rx;
277 stopy = 0;
278
279 while( stopx >= stopy )
280 {
281 u8g2_draw_ellipse_section(u8g2, x, y, x0, y0, option);
282 y++;
283 stopy += rxrx2;
284 err += ychg;
285 ychg += rxrx2;
286 if ( 2*err+xchg > 0 )
287 {
288 x--;
289 stopx -= ryry2;
290 err += xchg;
291 xchg += ryry2;
292 }
293 }
294
295 x = 0;
296 y = ry;
297
298 xchg = ry;
299 xchg *= ry;
300
301 ychg = 1;
302 ychg -= ry;
303 ychg -= ry;
304 ychg *= rx;
305 ychg *= rx;
306
307 err = 0;
308
309 stopx = 0;
310
311 stopy = rxrx2;
312 stopy *= ry;
313
314
315 while( stopx <= stopy )
316 {
317 u8g2_draw_ellipse_section(u8g2, x, y, x0, y0, option);
318 x++;
319 stopx += ryry2;
320 err += xchg;
321 xchg += ryry2;
322 if ( 2*err+ychg > 0 )
323 {
324 y--;
325 stopy -= rxrx2;
326 err += ychg;
327 ychg += rxrx2;
328 }
329 }
330
331 }
332
333 void u8g2_DrawEllipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option)
334 {
335 /* check for bounding box */
336 #ifdef U8G2_WITH_INTERSECTION
337 {
338 if ( u8g2_IsIntersection(u8g2, x0-rx, y0-ry, x0+rx+1, y0+ry+1) == 0 )
339 return;
340 }
341 #endif /* U8G2_WITH_INTERSECTION */
342
343 u8g2_draw_ellipse(u8g2, x0, y0, rx, ry, option);
344 }
345
346 /*==============================================*/
347 /* Filled Ellipse */
348
349 static void u8g2_draw_filled_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option) U8G2_NOINLINE;
350 static void u8g2_draw_filled_ellipse_section(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t x0, u8g2_uint_t y0, uint8_t option)
351 {
352 /* upper right */
353 if ( option & U8G2_DRAW_UPPER_RIGHT )
354 {
355 u8g2_DrawVLine(u8g2, x0+x, y0-y, y+1);
356 }
357
358 /* upper left */
359 if ( option & U8G2_DRAW_UPPER_LEFT )
360 {
361 u8g2_DrawVLine(u8g2, x0-x, y0-y, y+1);
362 }
363
364 /* lower right */
365 if ( option & U8G2_DRAW_LOWER_RIGHT )
366 {
367 u8g2_DrawVLine(u8g2, x0+x, y0, y+1);
368 }
369
370 /* lower left */
371 if ( option & U8G2_DRAW_LOWER_LEFT )
372 {
373 u8g2_DrawVLine(u8g2, x0-x, y0, y+1);
374 }
375 }
376
377 static void u8g2_draw_filled_ellipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option)
378 {
379 u8g2_uint_t x, y;
380 u8g2_long_t xchg, ychg;
381 u8g2_long_t err;
382 u8g2_long_t rxrx2;
383 u8g2_long_t ryry2;
384 u8g2_long_t stopx, stopy;
385
386 rxrx2 = rx;
387 rxrx2 *= rx;
388 rxrx2 *= 2;
389
390 ryry2 = ry;
391 ryry2 *= ry;
392 ryry2 *= 2;
393
394 x = rx;
395 y = 0;
396
397 xchg = 1;
398 xchg -= rx;
399 xchg -= rx;
400 xchg *= ry;
401 xchg *= ry;
402
403 ychg = rx;
404 ychg *= rx;
405
406 err = 0;
407
408 stopx = ryry2;
409 stopx *= rx;
410 stopy = 0;
411
412 while( stopx >= stopy )
413 {
414 u8g2_draw_filled_ellipse_section(u8g2, x, y, x0, y0, option);
415 y++;
416 stopy += rxrx2;
417 err += ychg;
418 ychg += rxrx2;
419 if ( 2*err+xchg > 0 )
420 {
421 x--;
422 stopx -= ryry2;
423 err += xchg;
424 xchg += ryry2;
425 }
426 }
427
428 x = 0;
429 y = ry;
430
431 xchg = ry;
432 xchg *= ry;
433
434 ychg = 1;
435 ychg -= ry;
436 ychg -= ry;
437 ychg *= rx;
438 ychg *= rx;
439
440 err = 0;
441
442 stopx = 0;
443
444 stopy = rxrx2;
445 stopy *= ry;
446
447
448 while( stopx <= stopy )
449 {
450 u8g2_draw_filled_ellipse_section(u8g2, x, y, x0, y0, option);
451 x++;
452 stopx += ryry2;
453 err += xchg;
454 xchg += ryry2;
455 if ( 2*err+ychg > 0 )
456 {
457 y--;
458 stopy -= rxrx2;
459 err += ychg;
460 ychg += rxrx2;
461 }
462 }
463
464 }
465
466 void u8g2_DrawFilledEllipse(u8g2_t *u8g2, u8g2_uint_t x0, u8g2_uint_t y0, u8g2_uint_t rx, u8g2_uint_t ry, uint8_t option)
467 {
468 /* check for bounding box */
469 #ifdef U8G2_WITH_INTERSECTION
470 {
471 if ( u8g2_IsIntersection(u8g2, x0-rx, y0-ry, x0+rx+1, y0+ry+1) == 0 )
472 return;
473 }
474 #endif /* U8G2_WITH_INTERSECTION */
475
476 u8g2_draw_filled_ellipse(u8g2, x0, y0, rx, ry, option);
477 }
478
479

mercurial