📄 guiarc.c
字号:
/*********************************************************************************************************** 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 : GUIARCFloat.CPurpose : Draw Arc routines based on floating point----------------------------------------------------------------------Version-Date---Author-Explanation----------------------------------------------------------------------2.00.00 000325 RS First release of the new algorithm----------------------------------------------------------------------Known problems or limitations with current version----------------------------------------------------------------------None.----------------------------------------------------------------------Open issues----------------------------------------------------------------------None---------------------------END-OF-HEADER------------------------------*/#include <stddef.h> /* needed for definition of NULL */#include <math.h>#include "GUI_Private.h"static void CalcX(int*px, int y, U32 r2) { int x =*px; U32 y2 = (U32)y*(U32)y; U32 r2y2 = r2-y2; U32 x2; if (y2>=r2) { *px=0; return; } /* x2 = r2-y2 */ do { x++; x2 =(U32)x*(U32)x; } while (x2 < r2y2); *px = x-1;}static float CalcInterSectLin(float y, float y0, float y1, float x0, float x1) { if (y1==y0) { return y0; } else { float Slope = (x1-x0)/(y1-y0); return (y-y0)*Slope+x0; }}static void _DrawArc(int x0, int y0, int rx, int ry, int Angle0, int Angle1, int xMul, int yMul) { float afx[4]; float afy[4]; float ri = rx-(GUI_Context.PenSize+1.5)/2; float ro = rx+(GUI_Context.PenSize+1.5)/2; float fAngle0 = Angle0*3.1415926/180; float fAngle1 = Angle1*3.1415926/180; float sin0 = sin(fAngle0); float sin1 = sin(fAngle1); float cos0 = cos(fAngle0); float cos1 = cos(fAngle1); U32 ri2 = ri*ri; U32 ro2 = ro*ro; int y, yMax, yMin; afy[0] = ri*sin0; afy[1] = ro*sin0; afy[2] = ri*sin1; afy[3] = ro*sin1; afx[0] = ri*cos0; afx[1] = ro*cos0; afx[2] = ri*cos1; afx[3] = ro*cos1; yMin = ceil(afy[0]); yMax = floor(afy[3]); /* Use Clipping rect to reduce calculation (if possible) */ if (GUI_Context.pClipRect_HL) { if (yMul ==1) { if (yMax > (GUI_Context.pClipRect_HL->y1 -y0)) yMax = (GUI_Context.pClipRect_HL->y1 -y0); if (yMin < (GUI_Context.pClipRect_HL->y0 -y0)) yMin = (GUI_Context.pClipRect_HL->y0 -y0); } if (yMul == -1) { if (yMin > (GUI_Context.pClipRect_HL->y1 -y0)) yMin = (GUI_Context.pClipRect_HL->y1 -y0); if (yMax < (GUI_Context.pClipRect_HL->y0 -y0)) yMax = (GUI_Context.pClipRect_HL->y0 -y0); } } /* Start drawing lines ... */ { int xMinDisp, xMaxDisp, xMin=0,xMax=0; for (y=yMax; y>=yMin; y--) { CalcX(&xMin, y, ri2); CalcX(&xMax, y, ro2); if ((float)y< afy[1]) { xMaxDisp = CalcInterSectLin(y,afy[0], afy[1], afx[0], afx[1]); } else { xMaxDisp = xMax; } if ((float)y > afy[2]) { xMinDisp = CalcInterSectLin(y,afy[2], afy[3], afx[2], afx[3]); } else { xMinDisp = xMin; } if (xMul>0) LCD_HL_DrawHLine(xMinDisp+x0, yMul*y+y0, xMaxDisp+x0); else LCD_HL_DrawHLine(-xMaxDisp+x0, yMul*y+y0, -xMinDisp+x0); } }#if 0 /* Test code */{ int i; GUI_SetColor( GUI_WHITE ); for (i=0; i<4; i++) LCD_HL_DrawPixel(afx[i]+x0, afy[i]+y0);}#endif GUI_USE_PARA(ry);}void GL_DrawArc (int x0, int y0, int rx, int ry, int a0, int a1) { int aEnd; a0+=360; a1+=360; while (a0>=360) { a0 -= 360; a1 -= 360; }/* Do first quadrant 0-90 degree */DoFirst: if (a1<=0) return; if (a0<90) { if (a0<0) a0=0; aEnd = (a1<90) ? a1 : 90; _DrawArc(x0,y0,rx,ry,a0,aEnd, 1, -1); } a1-=90; a0-=90;/* Do second quadrant 90-180 degree */ if (a1<=0) return; if (a0<90) { if (a0<0) a0=0; aEnd = (a1<90) ? a1 : 90; _DrawArc(x0,y0,rx,ry,90-aEnd, 90-a0,-1,-1); } a1-=90; a0-=90;/* Do third quadrant 180-270 degree */ if (a1<=0) return; if (a0<90) { if (a0<0) a0=0; aEnd = (a1<90) ? a1 : 90; _DrawArc(x0,y0,rx,ry,a0,aEnd, -1, 1); } a1-=90; a0-=90;/* Do last quadrant 270-360 degree */ if (a1<=0) return; if (a0<90) { if (a0<0) a0=0; aEnd = (a1<90) ? a1 : 90; _DrawArc(x0,y0,rx,ry,90-aEnd, 90-a0,1,1); } a1-=90; a0-=90;goto DoFirst;}void GUI_DrawArc (int x0, int y0, int rx, int ry, int a0, int a1) { GUI_LOCK(); #if (GUI_WINSUPPORT) WM_ADDORG(x0,y0); WM_ITERATE_START(NULL) { #endif GL_DrawArc( x0, y0, rx, ry, a0, a1); #if (GUI_WINSUPPORT) } WM_ITERATE_END(); #endif GUI_UNLOCK();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -