home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c100 / 3.ddi / BGICLA.ZIP / POLYGON.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-11  |  10.5 KB  |  377 lines

  1. /**************************************************************************
  2.     Listing   -   POLYGON.CPP
  3.  
  4.  
  5.     Written by Kevin D. Weeks, April 1990
  6.     Released to the Public Domain
  7. */
  8.  
  9. #include <stdio.h>
  10. #include "line.hpp"
  11. #include "polygon.hpp"
  12.  
  13. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  14.     Constructor - creates an empty instance. all attributes are set to
  15.     zero or to the appropriate BGI defaults.
  16. */
  17. Polygon::Polygon(void)
  18. {
  19.     struct fillsettingstype  fill_type;
  20.  
  21.     // use BGI default fill_color and pattern
  22.     getfillsettings(&fill_type);
  23.     fill_color = (COLORS)fill_type.color;
  24.     fill_pattern = (fill_patterns)fill_type.pattern;
  25.  
  26.     sides = NULL;
  27.     num_sides = 0;
  28.     filled = FALSE;
  29.     visible = FALSE;
  30. }
  31.  
  32. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  33.     Constructor - the "copy constructor", Polygon(const Polygon &source),
  34.     won't accept a pointer easily so we define a separate pointer
  35.     constructor for convenience' sake.
  36. */
  37. Polygon::Polygon(const Polygon *source)
  38. {
  39.     int     i;
  40.  
  41.     num_sides = source->num_sides;
  42.  
  43.     // allocate this object's own array of pointers to Lines and then
  44.     // allocate each individual side
  45.     sides = new Line*[num_sides];
  46.     for (i = 0; i < num_sides; i++)
  47.         sides[i] = new Line(source->sides[i]);
  48.  
  49.     fill_color = source->fill_color;
  50.     fill_pattern = source->fill_pattern;
  51.  
  52.     visible = FALSE;
  53.     filled = FALSE;
  54. }
  55.  
  56. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  57.     Constructor - this method is passed an array of Points representing
  58.     each vertice on the polygon. except for the vertices and the number
  59.     of vertices. every other attribute can default.
  60. */
  61. Polygon::Polygon(const int num_vertices, const Point *vertex,
  62.                  const COLORS side_color, const COLORS init_color,
  63.                  const line_styles side_style, const line_widths side_width,
  64.                  const fill_patterns init_pattern)
  65. {
  66.     struct fillsettingstype  fill_type;
  67.     int     i;
  68.  
  69.     num_sides = num_vertices;
  70.  
  71.     // allocate this object's own array of pointers to Lines and then
  72.     // allocate each individual side
  73.     sides = new Line*[num_sides];
  74.     for (i = 0; i < num_sides; i++)
  75.     {
  76.         sides[i] = new Line(vertex[i],vertex[i + 1]);
  77.         // if not default then set attribute
  78.         if (side_color != (COLORS)DEFAULT)
  79.             sides[i]->set_color(side_color);
  80.         if (side_style != (line_styles)DEFAULT)
  81.             sides[i]->set_style(side_style);
  82.         if (side_width != (line_widths)DEFAULT)
  83.             sides[i]->set_width(side_width);
  84.     }
  85.  
  86.     if ((init_color == DEFAULT) || (init_pattern == DEFAULT))
  87.         getfillsettings(&fill_type);
  88.     if (init_color == DEFAULT)
  89.         fill_color = (COLORS)fill_type.color;
  90.     else
  91.         fill_color = init_color;
  92.     if (init_pattern == DEFAULT)
  93.         fill_pattern = (fill_patterns)fill_type.pattern;
  94.     else
  95.         fill_pattern = init_pattern;
  96.     visible = FALSE;
  97.     filled = FALSE;
  98. }
  99.  
  100. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  101.     Constructor - this method is passed an array of Lines representing
  102.     the sides on the polygon. except for the sides and the number of
  103.     sides. every other attribute can default.
  104. */
  105. Polygon::Polygon(const int no_sides, const Line init_side[],
  106.                  const COLORS side_color, const COLORS init_color,
  107.                  const line_styles side_style, const line_widths side_width,
  108.                  const fill_patterns init_pattern)
  109. {
  110.     struct fillsettingstype  fill_type;
  111.     int     i;
  112.  
  113.     num_sides = no_sides;
  114.  
  115.     // allocate this object's array of pointers to Lines and then
  116.     // allocate each individual side
  117.     sides = new Line*[num_sides];
  118.     for (i = 0; i < num_sides; i++)
  119.     {
  120.         sides[i] = new Line(init_side[i]);
  121.         // if not default then set attribute
  122.         if (side_color != (COLORS)DEFAULT)
  123.             sides[i]->set_color(side_color);
  124.         if (side_style != (line_styles)DEFAULT)
  125.             sides[i]->set_style(side_style);
  126.         if (side_width != (line_widths)DEFAULT)
  127.             sides[i]->set_width(side_width);
  128.     }
  129.  
  130.     if ((init_color == DEFAULT) || (init_pattern == DEFAULT))
  131.         getfillsettings(&fill_type);
  132.     if (init_color == DEFAULT)
  133.         fill_color = (COLORS)fill_type.color;
  134.     else
  135.         fill_color = init_color;
  136.     if (init_pattern == DEFAULT)
  137.         fill_pattern = (fill_patterns)fill_type.pattern;
  138.     else
  139.         fill_pattern = init_pattern;
  140.     visible = FALSE;
  141.     filled = FALSE;
  142. }
  143.  
  144. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  145.     Destructor - erases the polygon if it's visible and deletes the
  146.     sides.
  147. */
  148. Polygon::~Polygon(void)
  149. {
  150.     int     i;
  151.  
  152.     if (visible)
  153.         erase();
  154.  
  155.     if (sides == NULL)
  156.        return;
  157.     for (i = 0; i < num_sides; i++)
  158.         delete sides[i];
  159.     delete [num_sides] sides;
  160. }
  161.  
  162. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  163.     returns a reference to the specified side. if the side number is out
  164.     of range a reference to the 1st side is returned.
  165. */
  166. Line    &Polygon::side(const int side_number)
  167. {
  168.     if ((side_number <= num_sides) && (side_number > 0))
  169.         return *sides[side_number - 1];
  170.     else
  171.         return *sides[0];
  172. }
  173.  
  174. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  175.     sets the color of all the sides. to set the color of a specific side
  176.     use the side() method.
  177.     example:    Polygon::side(1).set_color(RED);
  178. */
  179. void    Polygon::set_side_color(COLORS new_color)
  180. {
  181.     int     i;
  182.  
  183.     for (i = 0; i < num_sides; i++)
  184.         sides[i]->set_color(new_color);
  185. }
  186.  
  187. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  188.     sets the line_style of all the sides.
  189. */
  190. void    Polygon::set_side_style(line_styles new_style)
  191. {
  192.     int     i;
  193.  
  194.     for (i = 0; i < num_sides; i++)
  195.         sides[i]->set_style(new_style);
  196. }
  197.  
  198. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  199.     sets the line_width of all the sides.
  200. */
  201. void    Polygon::set_side_width(line_widths new_width)
  202. {
  203.     int     i;
  204.  
  205.     for (i = 0; i < num_sides; i++)
  206.         sides[i]->set_width(new_width);
  207. }
  208.  
  209. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  210.     pattern can be set whether the polygon is visible or not
  211. */
  212. void    Polygon::set_pattern(const fill_patterns new_pattern)
  213. {
  214.     if (visible)
  215.     {
  216.         erase();
  217.         fill_pattern = new_pattern;
  218.         draw();
  219.     }
  220.     else
  221.         fill_pattern = new_pattern;
  222. }
  223.  
  224. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  225.     color can be set whether the polygon is visible or not
  226. */
  227. void    Polygon::set_color(const COLORS new_color)
  228. {
  229.     if (visible)
  230.     {
  231.         erase();
  232.         fill_color = new_color;
  233.         draw();
  234.     }
  235.     else
  236.         fill_color = new_color;
  237. }
  238.  
  239. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  240.     fills an existing polygon.
  241. */
  242. void    Polygon::fill(void)
  243. {
  244.     struct fillsettingstype hold;
  245.     int                     *vertice;
  246.     int                     i, j;
  247.  
  248.     if (!visible)
  249.     {
  250.         filled = TRUE;
  251.         return;
  252.     }
  253.  
  254.     // create and initialize an array to hold the vertices to be passed
  255.     // to fillpoly()
  256.     if ((vertice = new int[num_sides * 2]) == NULL)
  257.         return;
  258.     for (j = 0, i = 0; i < num_sides; i++)
  259.     {
  260.         vertice[j++] = sides[i]->get_start().get_x();
  261.         vertice[j++] = sides[i]->get_start().get_y();
  262.     }
  263.  
  264.     // preserve BGI defaults
  265.     getfillsettings(&hold);
  266.  
  267.     // specify the fill pattern and color for this object and draw it
  268.     setfillstyle(fill_pattern,fill_color);
  269.     fillpoly(num_sides,vertice);
  270.  
  271.     // restore the BGI defaults and re-draw the sides
  272.     setfillstyle(hold.pattern,hold.color);
  273.     for (i = 0; i < num_sides; i++)
  274.         sides[i]->draw();
  275.     filled = TRUE;
  276.     delete vertice;
  277. }
  278.  
  279. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  280.     clears a filled polygon to the background color.
  281. */
  282. void    Polygon::empty(void)
  283. {
  284.     if (visible)
  285.     {
  286.         erase();
  287.         filled = FALSE;
  288.         draw();
  289.     }
  290.     filled = FALSE;
  291. }
  292.  
  293. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  294.     draw the polygon. if the filled flag is set then use the fill method
  295.     else just have the sides draw themselves.
  296. */
  297. void    Polygon::draw(void)
  298. {
  299.     int     i;
  300.  
  301.     visible = TRUE;
  302.     if (filled)
  303.         fill();
  304.     else
  305.         for (i = 0; i < num_sides; i++)
  306.             sides[i]->draw();
  307. }
  308.  
  309. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  310. void    Polygon::erase(void)
  311. {
  312.     int     i;
  313.     fill_patterns   hold_pattern;
  314.     COLORS          hold_color;
  315.  
  316.     if (filled)
  317.     {
  318.         // preserve this object's settings
  319.         hold_pattern = fill_pattern;
  320.         hold_color = fill_color;
  321.  
  322.         // fill the polygon in the background color
  323.         fill_pattern = SOLID_FILL;
  324.         fill_color = (COLORS)getbkcolor();
  325.         fill();
  326.  
  327.         // restore this object's original settings
  328.         fill_pattern = hold_pattern;
  329.         fill_color = hold_color;
  330.     }
  331.  
  332.     for (i = 0; i < num_sides; i++)
  333.         sides[i]->erase();
  334.     visible = FALSE;
  335. }
  336.  
  337. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  338. void    Polygon::move_relative(Point &distance)
  339. {
  340.     int     i;
  341.  
  342.     erase();
  343.     for (i = 0; i < num_sides; i++)
  344.         sides[i]->move_relative(distance);
  345.     draw();
  346. }
  347.  
  348. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  349. void    Polygon::move_absolute(Point &new_location, Point &reference)
  350. {
  351.     int     i;
  352.     Point   distance;
  353.  
  354.     erase();
  355.     distance = new_location - reference;
  356.     move_relative(distance);
  357.     draw();
  358. }
  359.  
  360. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  361.     this is the private method used by the copy constructor and the =
  362.     operator. Note that the visible attribute is forced to FALSE.
  363. */
  364. Polygon &Polygon::copy(const Polygon &source)
  365. {
  366.     int     i;
  367.  
  368.     num_sides = source.num_sides;
  369.     sides = new Line*[num_sides];
  370.     for (i = 0; i < num_sides; i++)
  371.         sides[i] = new Line(source.sides[i]);
  372.     visible = FALSE;
  373.     fill_color = source.fill_color;
  374.     fill_pattern = source.fill_pattern;
  375.     return *this;
  376. }
  377.