========
Polygons
========

A polygon defines a flat surface in space, and is composed of an edges and a face. Polygons may be concave or convex, but must be planar (the behavior of non-planar polygons is undefined). One way to ensure that polygons sent to |HPSNOW| are planar is to break up your polygons into triangles, since triangles are always planar. Polygons are assumed to be closed shapes, therefore it is not necessary to specify the last point as |HPSNOW| will close the polygon automatically.

Polygons can be thought of as a simpler alternative to :doc:`shells <0201_shells>`. Polygons are implicitly connected, so inserting them is faster and easier. This makes them a good replacement for small, simple shells. They also have a more efficient representation in memory when compared to shells. However, they are not as capable - for example, they cannot be smooth shaded, multi-colored, textured, nor can attributes be set on their sub-parts. Inserting a polygon can be done in the following way:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_polygons.cpp
		   :start-after: //! [0206_a]
		   :end-before: //! [0206_a]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_polygons.cs
		   :start-after: //! [0206_a]
		   :end-before: //! [0206_a]
		   
.. image:: images/polygon.png

*A simple polygon*

**NOTE:** When inserting points, if the first point is the same as the last point, |HPSNOW| will eliminate the last point in order to optimize the polygon. This is important to remember if you later edit the polygon, because the number of points will be different. If you try to index a point that is outside the range of the number of polygon points, you will get an ``HPS::IndexOutOfRange`` exception.

The shape above could have been drawn as a polyline. However, an important distinction to note is that a  polyline is made up of only **lines** whereas a polygon, like all faceted objects, always has **edges** and faces. Therefore, edge attributes, such as weight, are controlled using the segment's ``HPS::EdgeAttributeControl`` and colors are controlled by the ``HPS::MaterialMappingControl``. Setting attributes is done in this way:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_polygons.cpp
		   :start-after: //! [0206_b]
		   :end-before: //! [0206_b]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_polygons.cs
		   :start-after: //! [0206_b]
		   :end-before: //! [0206_b]

Editing polygons is relatively simple. Modifications can be made via deletion, replacing, or inserting points. Using the ``HPS::PolygonKey``, the code below operates on the original polygon and transforms it into something that looks completely different. Note that after the polygon is inserted, it is possible to reuse the ``PointArray`` without any detrimental results:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_polygons.cpp
		   :start-after: //! [0206_c]
		   :end-before: //! [0206_c]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_polygons.cs
		   :start-after: //! [0206_c]
		   :end-before: //! [0206_c]
		   
.. image:: images/edited_polygon.png

*The edited polygon*

If you find you need to convert a polygon into a shell to take advantage of some of the advanced options offered by shells, you can perform the conversion as described in :ref:`this section <prog_guide/0201_shells:Creating a shell from other types of geometry>`.
