home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- Listing - POLYGON.CPP
-
-
- Written by Kevin D. Weeks, April 1990
- Released to the Public Domain
- */
-
- #include <stdio.h>
- #include "line.hpp"
- #include "polygon.hpp"
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- Constructor - creates an empty instance. all attributes are set to
- zero or to the appropriate BGI defaults.
- */
- Polygon::Polygon(void)
- {
- struct fillsettingstype fill_type;
-
- // use BGI default fill_color and pattern
- getfillsettings(&fill_type);
- fill_color = (COLORS)fill_type.color;
- fill_pattern = (fill_patterns)fill_type.pattern;
-
- sides = NULL;
- num_sides = 0;
- filled = FALSE;
- visible = FALSE;
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- Constructor - the "copy constructor", Polygon(const Polygon &source),
- won't accept a pointer easily so we define a separate pointer
- constructor for convenience' sake.
- */
- Polygon::Polygon(const Polygon *source)
- {
- int i;
-
- num_sides = source->num_sides;
-
- // allocate this object's own array of pointers to Lines and then
- // allocate each individual side
- sides = new Line*[num_sides];
- for (i = 0; i < num_sides; i++)
- sides[i] = new Line(source->sides[i]);
-
- fill_color = source->fill_color;
- fill_pattern = source->fill_pattern;
-
- visible = FALSE;
- filled = FALSE;
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- Constructor - this method is passed an array of Points representing
- each vertice on the polygon. except for the vertices and the number
- of vertices. every other attribute can default.
- */
- Polygon::Polygon(const int num_vertices, const Point *vertex,
- const COLORS side_color, const COLORS init_color,
- const line_styles side_style, const line_widths side_width,
- const fill_patterns init_pattern)
- {
- struct fillsettingstype fill_type;
- int i;
-
- num_sides = num_vertices;
-
- // allocate this object's own array of pointers to Lines and then
- // allocate each individual side
- sides = new Line*[num_sides];
- for (i = 0; i < num_sides; i++)
- {
- sides[i] = new Line(vertex[i],vertex[i + 1]);
- // if not default then set attribute
- if (side_color != (COLORS)DEFAULT)
- sides[i]->set_color(side_color);
- if (side_style != (line_styles)DEFAULT)
- sides[i]->set_style(side_style);
- if (side_width != (line_widths)DEFAULT)
- sides[i]->set_width(side_width);
- }
-
- if ((init_color == DEFAULT) || (init_pattern == DEFAULT))
- getfillsettings(&fill_type);
- if (init_color == DEFAULT)
- fill_color = (COLORS)fill_type.color;
- else
- fill_color = init_color;
- if (init_pattern == DEFAULT)
- fill_pattern = (fill_patterns)fill_type.pattern;
- else
- fill_pattern = init_pattern;
- visible = FALSE;
- filled = FALSE;
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- Constructor - this method is passed an array of Lines representing
- the sides on the polygon. except for the sides and the number of
- sides. every other attribute can default.
- */
- Polygon::Polygon(const int no_sides, const Line init_side[],
- const COLORS side_color, const COLORS init_color,
- const line_styles side_style, const line_widths side_width,
- const fill_patterns init_pattern)
- {
- struct fillsettingstype fill_type;
- int i;
-
- num_sides = no_sides;
-
- // allocate this object's array of pointers to Lines and then
- // allocate each individual side
- sides = new Line*[num_sides];
- for (i = 0; i < num_sides; i++)
- {
- sides[i] = new Line(init_side[i]);
- // if not default then set attribute
- if (side_color != (COLORS)DEFAULT)
- sides[i]->set_color(side_color);
- if (side_style != (line_styles)DEFAULT)
- sides[i]->set_style(side_style);
- if (side_width != (line_widths)DEFAULT)
- sides[i]->set_width(side_width);
- }
-
- if ((init_color == DEFAULT) || (init_pattern == DEFAULT))
- getfillsettings(&fill_type);
- if (init_color == DEFAULT)
- fill_color = (COLORS)fill_type.color;
- else
- fill_color = init_color;
- if (init_pattern == DEFAULT)
- fill_pattern = (fill_patterns)fill_type.pattern;
- else
- fill_pattern = init_pattern;
- visible = FALSE;
- filled = FALSE;
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- Destructor - erases the polygon if it's visible and deletes the
- sides.
- */
- Polygon::~Polygon(void)
- {
- int i;
-
- if (visible)
- erase();
-
- if (sides == NULL)
- return;
- for (i = 0; i < num_sides; i++)
- delete sides[i];
- delete [num_sides] sides;
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- returns a reference to the specified side. if the side number is out
- of range a reference to the 1st side is returned.
- */
- Line &Polygon::side(const int side_number)
- {
- if ((side_number <= num_sides) && (side_number > 0))
- return *sides[side_number - 1];
- else
- return *sides[0];
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- sets the color of all the sides. to set the color of a specific side
- use the side() method.
- example: Polygon::side(1).set_color(RED);
- */
- void Polygon::set_side_color(COLORS new_color)
- {
- int i;
-
- for (i = 0; i < num_sides; i++)
- sides[i]->set_color(new_color);
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- sets the line_style of all the sides.
- */
- void Polygon::set_side_style(line_styles new_style)
- {
- int i;
-
- for (i = 0; i < num_sides; i++)
- sides[i]->set_style(new_style);
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- sets the line_width of all the sides.
- */
- void Polygon::set_side_width(line_widths new_width)
- {
- int i;
-
- for (i = 0; i < num_sides; i++)
- sides[i]->set_width(new_width);
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- pattern can be set whether the polygon is visible or not
- */
- void Polygon::set_pattern(const fill_patterns new_pattern)
- {
- if (visible)
- {
- erase();
- fill_pattern = new_pattern;
- draw();
- }
- else
- fill_pattern = new_pattern;
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- color can be set whether the polygon is visible or not
- */
- void Polygon::set_color(const COLORS new_color)
- {
- if (visible)
- {
- erase();
- fill_color = new_color;
- draw();
- }
- else
- fill_color = new_color;
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- fills an existing polygon.
- */
- void Polygon::fill(void)
- {
- struct fillsettingstype hold;
- int *vertice;
- int i, j;
-
- if (!visible)
- {
- filled = TRUE;
- return;
- }
-
- // create and initialize an array to hold the vertices to be passed
- // to fillpoly()
- if ((vertice = new int[num_sides * 2]) == NULL)
- return;
- for (j = 0, i = 0; i < num_sides; i++)
- {
- vertice[j++] = sides[i]->get_start().get_x();
- vertice[j++] = sides[i]->get_start().get_y();
- }
-
- // preserve BGI defaults
- getfillsettings(&hold);
-
- // specify the fill pattern and color for this object and draw it
- setfillstyle(fill_pattern,fill_color);
- fillpoly(num_sides,vertice);
-
- // restore the BGI defaults and re-draw the sides
- setfillstyle(hold.pattern,hold.color);
- for (i = 0; i < num_sides; i++)
- sides[i]->draw();
- filled = TRUE;
- delete vertice;
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- clears a filled polygon to the background color.
- */
- void Polygon::empty(void)
- {
- if (visible)
- {
- erase();
- filled = FALSE;
- draw();
- }
- filled = FALSE;
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- draw the polygon. if the filled flag is set then use the fill method
- else just have the sides draw themselves.
- */
- void Polygon::draw(void)
- {
- int i;
-
- visible = TRUE;
- if (filled)
- fill();
- else
- for (i = 0; i < num_sides; i++)
- sides[i]->draw();
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- void Polygon::erase(void)
- {
- int i;
- fill_patterns hold_pattern;
- COLORS hold_color;
-
- if (filled)
- {
- // preserve this object's settings
- hold_pattern = fill_pattern;
- hold_color = fill_color;
-
- // fill the polygon in the background color
- fill_pattern = SOLID_FILL;
- fill_color = (COLORS)getbkcolor();
- fill();
-
- // restore this object's original settings
- fill_pattern = hold_pattern;
- fill_color = hold_color;
- }
-
- for (i = 0; i < num_sides; i++)
- sides[i]->erase();
- visible = FALSE;
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- void Polygon::move_relative(Point &distance)
- {
- int i;
-
- erase();
- for (i = 0; i < num_sides; i++)
- sides[i]->move_relative(distance);
- draw();
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- void Polygon::move_absolute(Point &new_location, Point &reference)
- {
- int i;
- Point distance;
-
- erase();
- distance = new_location - reference;
- move_relative(distance);
- draw();
- }
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- this is the private method used by the copy constructor and the =
- operator. Note that the visible attribute is forced to FALSE.
- */
- Polygon &Polygon::copy(const Polygon &source)
- {
- int i;
-
- num_sides = source.num_sides;
- sides = new Line*[num_sides];
- for (i = 0; i < num_sides; i++)
- sides[i] = new Line(source.sides[i]);
- visible = FALSE;
- fill_color = source.fill_color;
- fill_pattern = source.fill_pattern;
- return *this;
- }
-