GUICirc.c
上传用户:zbk8730
上传日期:2017-08-10
资源大小:12168k
文件大小:7k
- /*
- *********************************************************************************************************
- * uC/GUI
- * Universal graphic software for embedded applications
- *
- * (c) Copyright 2002, Micrium Inc., Weston, FL
- * (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
- *
- * 礐/GUI is protected by international copyright laws. Knowledge of the
- * source code may not be used to write a similar product. This file may
- * only be used in accordance with a license and should not be redistributed
- * in any way. We appreciate your understanding and fairness.
- *
- ----------------------------------------------------------------------
- File : GUICirc.C
- Purpose : Circle and ellipse drawing functions
- ----------------------------------------------------------------------
- Version-Date---Author-Explanation
- ----------------------------------------------------------------------
- 1.00.02 011115 JE a) GL_FillEllipse, GL_FillCircle, GL_DrawCircle changed
- 1.00.01 011113 JE a) GL_DrawEllipse changed
- 1.00.00 991206 RS First release
- ----------------------------------------------------------------------
- Known problems or limitations with current version
- ----------------------------------------------------------------------
- None.
- ----------------------------------------------------------------------
- Open issues
- ----------------------------------------------------------------------
- None
- ---------------------------END-OF-HEADER------------------------------
- */
- #include <stddef.h> /* needed for definition of NULL */
- #include "GUI_Private.H"
- /*
- *************************************************
- * *
- * Draw Circle *
- * *
- *************************************************
- */
- static void Draw8Point(int x0,int y0, int xoff, int yoff) {
- LCD_HL_DrawPixel(x0+xoff,y0+yoff);
- LCD_HL_DrawPixel(x0-xoff,y0+yoff);
- LCD_HL_DrawPixel(x0+yoff,y0+xoff);
- LCD_HL_DrawPixel(x0+yoff,y0-xoff);
- if (yoff) {
- LCD_HL_DrawPixel(x0+xoff,y0-yoff);
- LCD_HL_DrawPixel(x0-xoff,y0-yoff);
- LCD_HL_DrawPixel(x0-yoff,y0+xoff);
- LCD_HL_DrawPixel(x0-yoff,y0-xoff);
- }
- }
- void GL_DrawCircle(int x0, int y0, int r) {
- I32 i;
- int imax = ((I32)((I32)r*707))/1000+1;
- I32 sqmax = (I32)r*(I32)r+(I32)r/2;
- I32 y=r;
- Draw8Point(x0,y0,r,0);
- for (i=1; i<= imax; i++) {
- if ((i*i+y*y) >sqmax) {
- Draw8Point(x0,y0,i,y);
- y--;
- }
- Draw8Point(x0,y0,i,y);
- }
- }
- void GUI_DrawCircle (int x0, int y0, int r) {
- #if (GUI_WINSUPPORT)
- GUI_RECT Rect;
- #endif
- GUI_LOCK();
- #if (GUI_WINSUPPORT)
- WM_ADDORG(x0,y0);
- Rect.x0 = x0-r;
- Rect.x1 = x0+r;
- Rect.y0 = y0-r;
- Rect.y1 = y0+r;
- WM_ITERATE_START(&Rect); {
- #endif
- GL_DrawCircle( x0, y0, r);
- #if (GUI_WINSUPPORT)
- } WM_ITERATE_END();
- #endif
- GUI_UNLOCK();
- }
- /*
- *************************************************
- * *
- * Fill Circle *
- * *
- *************************************************
- */
- void GL_FillCircle (int x0, int y0, int r) {
- I32 i;
- int imax = ((I32)((I32)r*707))/1000+1;
- I32 sqmax = (I32)r*(I32)r+(I32)r/2;
- I32 x=r;
- LCD_HL_DrawHLine(x0-r,y0,x0+r);
- for (i=1; i<= imax; i++) {
- if ((i*i+x*x) >sqmax) {
- /* draw lines from outside */
- if (x>imax) {
- LCD_HL_DrawHLine (x0-i+1,y0+x, x0+i-1);
- LCD_HL_DrawHLine (x0-i+1,y0-x, x0+i-1);
- }
- x--;
- }
- /* draw lines from inside (center) */
- LCD_HL_DrawHLine(x0-x,y0+i, x0+x);
- LCD_HL_DrawHLine(x0-x,y0-i, x0+x);
- }
- }
- void GUI_FillCircle (int x0, int y0, int r) {
- GUI_LOCK();
- #if (GUI_WINSUPPORT)
- WM_ADDORG(x0,y0);
- WM_ITERATE_START(NULL); {
- #endif
- GL_FillCircle(x0,y0,r);
- #if (GUI_WINSUPPORT)
- } WM_ITERATE_END();
- #endif
- GUI_UNLOCK();
- }
- /*
- *********************************************************
- * *
- * Ellipse drawing / filling *
- * *
- *********************************************************
- The most efficient way to calculate the ellipse positions
- is using the knowledge that the ellipse is just circle which has
- compressed (or stretched) in one direction. For a circle, the
- following equation holds true for all points located on the border of
- it:
- x^2 + y(x)^2 = r^2 = const
- Therefor, for an ellipse we can make use of the following equation:
- (ry*x)^2 + (rx*y(x))^2 = (ry*rx)^2 = const
- */
- void GL_FillEllipse (int x0, int y0, int rx, int ry) {
- I32 OutConst, Sum, SumY;
- int x,y;
- U32 _rx = rx;
- U32 _ry = ry;
- OutConst = _rx*_rx*_ry*_ry /* Constant as explaint above */
- +(_rx*_rx*_ry>>1); /* To compensate for rounding */
- x = rx;
- for (y=0; y<=ry; y++) {
- SumY =((I32)(rx*rx))*((I32)(y*y)); /* Does not change in loop */
- while (Sum = SumY + ((I32)(ry*ry))*((I32)(x*x)),
- (x>0) && (Sum>OutConst))
- {
- x--;
- }
- LCD_HL_DrawHLine(x0-x, y0+y, x0+x);
- if (y)
- LCD_HL_DrawHLine(x0-x, y0-y, x0+x);
- }
- }
- void GUI_FillEllipse (int x0, int y0, int rx, int ry) {
- #if (GUI_WINSUPPORT)
- GUI_RECT r;
- #endif
- GUI_LOCK();
- #if (GUI_WINSUPPORT)
- WM_ADDORG(x0,y0);
- /* Calc rectangle in order to avoid unnecessary drawing ops. */
- r.x0 = x0-rx; r.x1 = x0+rx; r.y0 = y0-ry; r.y1 = y0+ry;
- WM_ITERATE_START(&r); {
- #endif
- GL_FillEllipse (x0,y0, rx, ry);
- #if (GUI_WINSUPPORT)
- } WM_ITERATE_END();
- #endif
- GUI_UNLOCK();
- }
- void GL_DrawEllipse (int x0, int y0, int rx, int ry) {
- I32 OutConst, Sum, SumY;
- int x,y;
- int xOld;
- U32 _rx = rx;
- U32 _ry = ry;
- OutConst = _rx*_rx*_ry*_ry /* Constant as explaint above */
- +(_rx*_rx*_ry>>1); /* To compensate for rounding */
- xOld = x = rx;
- for (y=0; y<=ry; y++) {
- if (y==ry) {
- x=0;
- } else {
- SumY =((I32)(rx*rx))*((I32)(y*y)); /* Does not change in loop */
- while (Sum = SumY + ((I32)(ry*ry))*((I32)(x*x)),
- (x>0) && (Sum>OutConst)) x--;
- }
- /* Since we draw lines, we can not draw on the first
- iteration
- */
- if (y) {
- GL_DrawLine1(x0-xOld,y0-y+1,x0-x,y0-y);
- GL_DrawLine1(x0-xOld,y0+y-1,x0-x,y0+y);
- GL_DrawLine1(x0+xOld,y0-y+1,x0+x,y0-y);
- GL_DrawLine1(x0+xOld,y0+y-1,x0+x,y0+y);
- }
- xOld = x;
- }
- }
- void GUI_DrawEllipse (int x0, int y0, int rx, int ry) {
- #if (GUI_WINSUPPORT)
- GUI_RECT r;
- #endif
- GUI_LOCK();
- #if (GUI_WINSUPPORT)
- WM_ADDORG(x0,y0);
- /* Calc rectangle in order to avoid unnecessary drawing ops. */
- r.x0 = x0-rx; r.x1 = x0+rx; r.y0 = y0-ry; r.y1 = y0+ry;
- WM_ITERATE_START(&r); {
- #endif
- GL_DrawEllipse(x0, y0, rx, ry);
- #if (GUI_WINSUPPORT)
- } WM_ITERATE_END();
- #endif
- GUI_UNLOCK();
- }