guiarc.c
上传用户:zbk8730
上传日期:2017-08-10
资源大小:12168k
文件大小:5k
源码类别:

uCOS

开发平台:

C/C++

  1. /*
  2. *********************************************************************************************************
  3. *                                                uC/GUI
  4. *                        Universal graphic software for embedded applications
  5. *
  6. *                       (c) Copyright 2002, Micrium Inc., Weston, FL
  7. *                       (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
  8. *
  9. *              礐/GUI is protected by international copyright laws. Knowledge of the
  10. *              source code may not be used to write a similar product. This file may
  11. *              only be used in accordance with a license and should not be redistributed
  12. *              in any way. We appreciate your understanding and fairness.
  13. *
  14. ----------------------------------------------------------------------
  15. File        : GUIARCFloat.C
  16. Purpose     : Draw Arc routines based on floating point
  17. ----------------------------------------------------------------------
  18. Version-Date---Author-Explanation
  19. ----------------------------------------------------------------------
  20. 2.00.00 000325 RS     First release of the new algorithm
  21. ----------------------------------------------------------------------
  22. Known problems or limitations with current version
  23. ----------------------------------------------------------------------
  24. None.
  25. ----------------------------------------------------------------------
  26. Open issues
  27. ----------------------------------------------------------------------
  28. None
  29. ---------------------------END-OF-HEADER------------------------------
  30. */
  31. #include <stddef.h>           /* needed for definition of NULL */
  32. #include <math.h>
  33. #include "GUI_Private.h"
  34. static void CalcX(int*px, int y, U32 r2) {
  35.   int x =*px;
  36.   U32 y2 = (U32)y*(U32)y;
  37.   U32 r2y2 = r2-y2;
  38.   U32 x2;
  39.   if (y2>=r2) {
  40.     *px=0;
  41. return;
  42. }
  43.   /* x2 = r2-y2 */
  44.   do {
  45.     x++;
  46.     x2 =(U32)x*(U32)x;
  47. } while (x2 < r2y2);
  48. *px = x-1;
  49. }
  50. static float CalcInterSectLin(float y, float y0, float y1, float x0, float x1) {
  51.   if (y1==y0) {
  52.   return y0;
  53. } else {
  54.     float Slope = (x1-x0)/(y1-y0);
  55.    return (y-y0)*Slope+x0;
  56. }
  57. }
  58. static void _DrawArc(int x0, int y0, int rx, int ry, int Angle0, int Angle1, int xMul, int yMul) {
  59.   float afx[4];
  60.   float afy[4];
  61. float ri = rx-(GUI_Context.PenSize+1.5)/2;
  62. float ro = rx+(GUI_Context.PenSize+1.5)/2;
  63.   float fAngle0 = Angle0*3.1415926/180;
  64.   float fAngle1 = Angle1*3.1415926/180;
  65.   float sin0 = sin(fAngle0); 
  66.   float sin1 = sin(fAngle1); 
  67.   float cos0 = cos(fAngle0); 
  68.   float cos1 = cos(fAngle1); 
  69.   U32   ri2 = ri*ri;
  70.   U32   ro2 = ro*ro;
  71. int y, yMax, yMin;
  72. afy[0] = ri*sin0;
  73. afy[1] = ro*sin0;
  74. afy[2] = ri*sin1;
  75. afy[3] = ro*sin1;
  76. afx[0] = ri*cos0;
  77. afx[1] = ro*cos0;
  78. afx[2] = ri*cos1;
  79. afx[3] = ro*cos1;
  80. yMin = ceil(afy[0]);
  81.   yMax = floor(afy[3]);
  82.   /* Use Clipping rect to reduce calculation (if possible) */
  83.   if (GUI_Context.pClipRect_HL) {
  84.     if (yMul ==1) {
  85.       if (yMax > (GUI_Context.pClipRect_HL->y1 -y0))
  86.         yMax = (GUI_Context.pClipRect_HL->y1 -y0);
  87.       if (yMin < (GUI_Context.pClipRect_HL->y0 -y0))
  88.         yMin = (GUI_Context.pClipRect_HL->y0 -y0);
  89.     }
  90.     if (yMul == -1) {
  91.       if (yMin > (GUI_Context.pClipRect_HL->y1 -y0))
  92.         yMin = (GUI_Context.pClipRect_HL->y1 -y0);
  93.       if (yMax < (GUI_Context.pClipRect_HL->y0 -y0))
  94.         yMax = (GUI_Context.pClipRect_HL->y0 -y0);
  95.     }
  96.   }
  97.   /* Start drawing lines ... */
  98.   {
  99.   int xMinDisp, xMaxDisp, xMin=0,xMax=0;
  100.     for (y=yMax; y>=yMin; y--) {
  101.       CalcX(&xMin, y, ri2);
  102.       CalcX(&xMax, y, ro2);
  103.       if ((float)y< afy[1]) {
  104.         xMaxDisp = CalcInterSectLin(y,afy[0], afy[1], afx[0], afx[1]);
  105. } else {
  106.         xMaxDisp = xMax;
  107. }
  108.       if ((float)y > afy[2]) {
  109.         xMinDisp = CalcInterSectLin(y,afy[2], afy[3], afx[2], afx[3]);
  110. } else {
  111.         xMinDisp = xMin;
  112. }
  113.       if (xMul>0)
  114.         LCD_HL_DrawHLine(xMinDisp+x0, yMul*y+y0, xMaxDisp+x0);
  115.       else
  116.         LCD_HL_DrawHLine(-xMaxDisp+x0, yMul*y+y0, -xMinDisp+x0);
  117.     }
  118. }
  119. #if 0  /* Test code */
  120. {
  121.   int i;
  122.   GUI_SetColor( GUI_WHITE ); 
  123. for (i=0; i<4; i++)
  124.     LCD_HL_DrawPixel(afx[i]+x0, afy[i]+y0);
  125. }
  126. #endif
  127.   GUI_USE_PARA(ry);
  128. }
  129. void GL_DrawArc (int x0, int y0, int rx, int ry, int a0, int a1) {
  130.   int aEnd;
  131.   a0+=360;
  132. a1+=360;
  133. while (a0>=360) {
  134.     a0 -= 360;
  135.     a1 -= 360;
  136. }
  137. /* Do first quadrant 0-90 degree */
  138. DoFirst:
  139.   if (a1<=0)
  140.   return;
  141. if (a0<90) {
  142.     if (a0<0)
  143.   a0=0;
  144.     aEnd = (a1<90) ? a1 : 90;
  145.     _DrawArc(x0,y0,rx,ry,a0,aEnd, 1, -1);
  146. }
  147.   a1-=90;
  148. a0-=90;
  149. /* Do second quadrant 90-180 degree */
  150.   if (a1<=0)
  151.   return;
  152. if (a0<90) {
  153.     if (a0<0)
  154.   a0=0;
  155.     aEnd = (a1<90) ? a1 : 90;
  156.     _DrawArc(x0,y0,rx,ry,90-aEnd, 90-a0,-1,-1);
  157. }
  158.   a1-=90;
  159. a0-=90;
  160. /* Do third quadrant 180-270 degree */
  161.   if (a1<=0)
  162.   return;
  163. if (a0<90) {
  164.     if (a0<0)
  165.   a0=0;
  166.     aEnd = (a1<90) ? a1 : 90;
  167.     _DrawArc(x0,y0,rx,ry,a0,aEnd, -1, 1);
  168. }
  169.   a1-=90;
  170. a0-=90;
  171. /* Do last quadrant 270-360 degree */
  172.   if (a1<=0)
  173.   return;
  174. if (a0<90) {
  175.     if (a0<0)
  176.   a0=0;
  177.     aEnd = (a1<90) ? a1 : 90;
  178.     _DrawArc(x0,y0,rx,ry,90-aEnd, 90-a0,1,1);
  179. }
  180.   a1-=90;
  181. a0-=90;
  182. goto DoFirst;
  183. }
  184. void GUI_DrawArc (int x0, int y0, int rx, int ry, int a0, int a1) {
  185.   GUI_LOCK();
  186.   #if (GUI_WINSUPPORT)
  187.     WM_ADDORG(x0,y0);
  188.     WM_ITERATE_START(NULL) {
  189.   #endif
  190.   GL_DrawArc( x0, y0, rx, ry, a0, a1);
  191.   #if (GUI_WINSUPPORT)
  192.     } WM_ITERATE_END();
  193.   #endif
  194.   GUI_UNLOCK();
  195. }