?? guicirc.c
字號:
/*************************************************************************************************************
uC/GUI
嵌入式通用圖形軟件
File : GUICirc.C
Purpose : Circle and ellipse drawing functions
************************************************************************************************************/
#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();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -