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

A polygon defines a flat surface in space. The polygon has an edge and a face. The following code draws a unit square centered about the origin: 

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../../hoops_3df/demo/common/sanity/0700_docs_0011.cpp
		   :start-after: //! [insert_polygon]
		   :end-before: //! [insert_polygon]
		   
The square drawn by this code is similar to the unit square that we drew using a polyline, except that now we need to specify only four points, because HOOPS will close the polygon automatically (it is not an error to specify the closing point, but HOOPS will ignore the redundant point). In addition, a polygon defines a surface, so this unit square will be colored in. Finally, unlike a polyline, a polygon must be flat. The points specified must all lie on a plane (if they do not, HOOPS will not complain, but hidden-surface elimination and lighting are not guaranteed to work properly). One way to ensure that polygons sent to HOOPS are planar is to break up your polygons into triangles, since triangles are always planar. 


Polygon attributes
==================

A polygon consists of two separate parts: the edge and the face. You can set attributes on these two parts independently. You can also choose to display either or both of them using the ``Set_Visibility`` command. By default, both edges and faces are visible. To see just the outline of the polygon (so that it looks like a closed polyline), use:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../../hoops_3df/demo/common/sanity/0700_docs_0011.cpp
		   :start-after: //! [set_visibility_faces]
		   :end-before: //! [set_visibility_faces]
		   
To turn back on visibility for faces, you could use the same command with "faces=on", but it is usually better to unset visibility (so that it will inherit), rather than to turn it on explicitly. For example, to turn back on face visibility in a segment where it was turned off, you would say 

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../../hoops_3df/demo/common/sanity/0700_docs_0011.cpp
		   :start-after: //! [unset_one_visibility]
		   :end-before: //! [unset_one_visibility]
		   
That way, if you want to turn off all faces in a drawing (for example, to get a wireframe view), you can just set to off the visibility of faces on "?Picture", and all faces in the drawing will vanish. If you had explicitly set to on the visibility of faces somewhere down in the database, then those faces would remain on. 
  
To set the line weight of the polygon edge, use ``Set_Edge_Weight``. This will cause edges to be drawn in a fixed (screen space) size, and they will not scale as the object scales. However, HOOPS/3dGS also supports edges which will scale as the object is scaled or the camera changes. This is enabled by calling ``Set_Variable_Edge_Weight``. To set the line pattern of the edge, use ``Set_Edge_Pattern``. (These commands work analogously to ``Set_Line_Weight``, ``Set_Variable_Line_Weight``, and ``Set_Line_Pattern``.) Because polygon edges are always closed with no ends, the end cap line treatment of the edge pattern is ignored. The line-join treatment does work - it defines how the line segments in the edge of a polygon are joined (but, as is true for polylines, only if the edge weight is greater than 1). For example, to define a polygon with rounded corners, use:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../../hoops_3df/demo/common/sanity/0700_docs_0011.cpp
		   :start-after: //! [edges]
		   :end-before: //! [edges]

You can apply a pattern to the face of a polygon using ``Set_Face_Pattern``. A face pattern is similar to, but not the same as, a texture (in any case, a texture can be applied to only a shell, mesh, or window). As are line and edge patterns, a face pattern is specified figuratively. Here are some common face patterns (see ``Set_Face_Pattern`` in the HOOPS/3dGS Reference Manual for more patterns): 

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../../hoops_3df/demo/common/sanity/0700_docs_0011.cpp
		   :start-after: //! [face_pattern]
		   :end-before: //! [face_pattern]
		   
The pattern is drawn using the face-contrast color, whose default is white. To change the face-contrast color, use:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../../hoops_3df/demo/common/sanity/0700_docs_0011.cpp
		   :start-after: //! [set_color1]
		   :end-before: //! [set_color1]

Similarly, you can set the edge and face colors of a polygon: 

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../../hoops_3df/demo/common/sanity/0700_docs_0011.cpp
		   :start-after: //! [set_color2]
		   :end-before: //! [set_color2]
		   
By default, the edges and faces of a polygon are the same color. As an optimization, the edge of a polygon is drawn only if it is a color different from that of the face of the polygon, or if the edge weight is not 1. 


Clock example using a polygon
=============================

The program in :ref:`this section <prog_guide/3dgs/02_5_geometry_lines:Clock example using lines and markers>` created the border of the clock using a polyline. If we want to color in the face of the clock, we must use a polygon instead. There is no "ink" equivalent for polygons, so we must create an array to hold the points in the polygon::
  
	1   Point poly_points[12]; // point array
	2   // for each hour (starting from 1)
	3   for (int hour = 1; hour <= 12; hour++) {
	4 		double angle = hour * (3.14159/6.0);
	5 		float x = (float) sin(angle);
	6 		float y = (float) cos(angle); 
	7 		// rim and interior of clock face
	8 		poly_points[hour-1].set_point(
	9 			  rimr*x, rimr*y, 0.0);
	10 	// hour numerals
	11 	char buffer[8];
	12 	sprintf(buffer, "%d", hour);
	13 	HC_Insert_Text(numr * x, numr * y, 0.0,
	14 			buffer);
	15   }
	16  HC_Set_Color("faces=light silver");
	17  HC_Set_Edge_Weight(3.0);
	18  HC_Insert_Polygon(12, poly_points); 

*Clock example using a polygon.*

The loop now goes from 1 to 12 (12 iterations, instead of 13), because we do not need to close the polygon. The poly_points array, however, is subscripted from 0 to 11, so we have to subtract 1 from the subscript in line 8. 
  
Note that for now, we shall continue to specify the heuristic "no hidden surfaces", even though our scene now contains a surface. We shall discuss this issue in :doc:`the rendering section </prog_guide/3dgs/06_1_rendering_hidden_surfaces>`. 

Note that we changed the face color to light silver on line 16. If we had not done so, then the face color would be dark blue, just like the rest of the geometry in the face, and the hands would not be visible. You can also change the text color (for the hour numerals) and the edge color (for the rim of the clock) independently. You can change the face pattern using ``Set_Face_Pattern``. For a "retro" look, try changing the edge of the clock face to a dotted line, and the face pattern to dotted. 
