選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

216 行
4.9 KiB

  1. /*
  2. * libcaca ASCII-Art library
  3. * Copyright (c) 2002, 2003 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  19. * 02111-1307 USA
  20. */
  21. /** \file conic.c
  22. * \version \$Id$
  23. * \author Sam Hocevar <sam@zoy.org>
  24. * \brief Ellipse and circle drawing functions
  25. *
  26. * This file contains ellipse and circle drawing functions, both filled
  27. * and outline.
  28. */
  29. #include "config.h"
  30. #ifdef HAVE_INTTYPES_H
  31. # include <inttypes.h>
  32. #else
  33. typedef unsigned char uint8_t;
  34. #endif
  35. #include <stdlib.h>
  36. #include "caca.h"
  37. #include "caca_internals.h"
  38. static void ellipsepoints(int, int, int, int, char);
  39. void caca_draw_circle(int x, int y, int r, char c)
  40. {
  41. int test, dx, dy;
  42. /* Optimized Bresenham. Kick ass. */
  43. for(test = 0, dx = 0, dy = r ; dx <= dy ; dx++)
  44. {
  45. ellipsepoints(x, y, dx, dy, c);
  46. ellipsepoints(x, y, dy, dx, c);
  47. test += test > 0 ? dx - dy-- : dx;
  48. }
  49. }
  50. void caca_fill_ellipse(int xo, int yo, int a, int b, char c)
  51. {
  52. int d2;
  53. int x = 0;
  54. int y = b;
  55. int d1 = b*b - (a*a*b) + (a*a/4);
  56. while(a*a*y - a*a/2 > b*b*(x+1))
  57. {
  58. if(d1 < 0)
  59. {
  60. d1 += b*b*(2*x+1); /* XXX: "Computer Graphics" has + 3 here. */
  61. }
  62. else
  63. {
  64. d1 += b*b*(2*x*1) + a*a*(-2*y+2);
  65. caca_draw_line(xo - x, yo - y, xo + x, yo - y, c);
  66. caca_draw_line(xo - x, yo + y, xo + x, yo + y, c);
  67. y--;
  68. }
  69. x++;
  70. }
  71. caca_draw_line(xo - x, yo - y, xo + x, yo - y, c);
  72. caca_draw_line(xo - x, yo + y, xo + x, yo + y, c);
  73. d2 = b*b*(x+0.5)*(x+0.5) + a*a*(y-1)*(y-1) - a*a*b*b;
  74. while(y > 0)
  75. {
  76. if(d2 < 0)
  77. {
  78. d2 += b*b*(2*x+2) + a*a*(-2*y+3);
  79. x++;
  80. }
  81. else
  82. {
  83. d2 += a*a*(-2*y+3);
  84. }
  85. y--;
  86. caca_draw_line(xo - x, yo - y, xo + x, yo - y, c);
  87. caca_draw_line(xo - x, yo + y, xo + x, yo + y, c);
  88. }
  89. }
  90. void caca_draw_ellipse(int xo, int yo, int a, int b, char c)
  91. {
  92. int d2;
  93. int x = 0;
  94. int y = b;
  95. int d1 = b*b - (a*a*b) + (a*a/4);
  96. ellipsepoints(xo, yo, x, y, c);
  97. while(a*a*y - a*a/2 > b*b*(x+1))
  98. {
  99. if(d1 < 0)
  100. {
  101. d1 += b*b*(2*x+1); /* XXX: "Computer Graphics" has + 3 here. */
  102. }
  103. else
  104. {
  105. d1 += b*b*(2*x*1) + a*a*(-2*y+2);
  106. y--;
  107. }
  108. x++;
  109. ellipsepoints(xo, yo, x, y, c);
  110. }
  111. d2 = b*b*(x+0.5)*(x+0.5) + a*a*(y-1)*(y-1) - a*a*b*b;
  112. while(y > 0)
  113. {
  114. if(d2 < 0)
  115. {
  116. d2 += b*b*(2*x+2) + a*a*(-2*y+3);
  117. x++;
  118. }
  119. else
  120. {
  121. d2 += a*a*(-2*y+3);
  122. }
  123. y--;
  124. ellipsepoints(xo, yo, x, y, c);
  125. }
  126. }
  127. void caca_draw_thin_ellipse(int xo, int yo, int a, int b)
  128. {
  129. /* FIXME: this is not correct */
  130. int d2;
  131. int x = 0;
  132. int y = b;
  133. int d1 = b*b - (a*a*b) + (a*a/4);
  134. ellipsepoints(xo, yo, x, y, '-');
  135. while(a*a*y - a*a/2 > b*b*(x+1))
  136. {
  137. if(d1 < 0)
  138. {
  139. d1 += b*b*(2*x+1); /* XXX: "Computer Graphics" has + 3 here. */
  140. }
  141. else
  142. {
  143. d1 += b*b*(2*x*1) + a*a*(-2*y+2);
  144. y--;
  145. }
  146. x++;
  147. ellipsepoints(xo, yo, x, y, '-');
  148. }
  149. d2 = b*b*(x+0.5)*(x+0.5) + a*a*(y-1)*(y-1) - a*a*b*b;
  150. while(y > 0)
  151. {
  152. if(d2 < 0)
  153. {
  154. d2 += b*b*(2*x+2) + a*a*(-2*y+3);
  155. x++;
  156. }
  157. else
  158. {
  159. d2 += a*a*(-2*y+3);
  160. }
  161. y--;
  162. ellipsepoints(xo, yo, x, y, '|');
  163. }
  164. }
  165. static void ellipsepoints(int xo, int yo, int x, int y, char c)
  166. {
  167. uint8_t b = 0;
  168. if(xo + x >= 0 && xo + x < (int)caca_get_width())
  169. b |= 0x1;
  170. if(xo - x >= 0 && xo - x < (int)caca_get_width())
  171. b |= 0x2;
  172. if(yo + y >= 0 && yo + y < (int)caca_get_height())
  173. b |= 0x4;
  174. if(yo - y >= 0 && yo - y < (int)caca_get_height())
  175. b |= 0x8;
  176. if((b & (0x1|0x4)) == (0x1|0x4))
  177. caca_putchar(xo + x, yo + y, c);
  178. if((b & (0x2|0x4)) == (0x2|0x4))
  179. caca_putchar(xo - x, yo + y, c);
  180. if((b & (0x1|0x8)) == (0x1|0x8))
  181. caca_putchar(xo + x, yo - y, c);
  182. if((b & (0x2|0x8)) == (0x2|0x8))
  183. caca_putchar(xo - x, yo - y, c);
  184. }