Drawing any N-sided Polygon

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Environment: VC 5-6 , Windows 95/98/2000/NT/Me

Recently I had to develop a Graphics Software and wanted to
add support for drawing any N-sided Polygon. When I started, I thought
that I would have to develop code for every ‘N’ separately. After churning my head
in trigonometry for a couple of hours, I realized that effectively 20 lines of code
would do the job.

The figures are drawn (from the center) when you drag the mouse. The drawing mode
used is R2_NOT. When the user drags the mouse, the previous drawn figure is erased
and the new figure is drawn. You need to include "math.h" in your View.cpp file.

This checks when the User Starts dragging the mouse:

void CPolygonsView::OnLButtonDown(UINT nFlags,
                                  CPoint point)
{
  m_Drag = true; // for mouse drag check
  PointOrigin = point; // val when mouse drag starts
  CView::OnLButtonDown(nFlags, point);
}

void CPolygonsView::OnLButtonUp(UINT nFlags,
                                CPoint point)
{

  m_Drag = false;// for mouse drag check
  CView::OnLButtonUp(nFlags, point);
}

All the drawing is done in the MouseMove function. First the previously drawn figure is erased (by redrawing over it using R2_NOT). Then the new figure is drawn using the new coordinates. Note that for drawing the figure only 3 things are required:

  1. The center coordinates
  2. A vertex coordinate
  3. The number of sides of the polygon

The loop computes all the other coordinates using these elements and draws lines connecting one vertex to the other.

//value of pi used for trig calcs 
const double PI = 3.1415926;
void CPolygonsView::OnMouseMove(UINT nFlags,
                                CPoint point)
{
  // TODO: Add your message handler code
  // here and/or call default
  if (m_Drag && PointOrigin!=point)
  {                        // for mouse drag check
    CClientDC ClientDC(this); // graphics
    ClientDC.SetROP2(R2_NOT);
    double Ox , Oy , Px , Py;
    double phai ;
    //angle used by me to compute
    double theta ;
    //angle used by me to compute
    double hyp ;
    double x1 ;
    double mu ;
    double x2 ;
    double y2;

    int m_Sides = 3;//default figure = triangle
    Ox = PointOrigin.x;
    Oy = PointOrigin.y;
    Px = PointOld.x;
    Py = PointOld.y;
    phai = PI / ( m_Sides );
    theta = PI / 2 - phai;
    hyp = sqrt( ( Px - Ox ) * ( Px - Ox ) +
                ( Py - Oy ) * ( Py - Oy ) );
    //hyp = hypotnuse
    // erase the previous drawn polygon
    for ( int f = 0;f <m_Sides;f++)
    {
      x1 = hyp * cos( theta );
      mu = atan2( Py - Oy , Px - Ox );
      x2 = x1 * cos( ( mu - theta ) );
      y2 = x1 * sin( ( mu - theta ) );
      ClientDC.MoveTo( int( Px ) , int( Py ) );
      ClientDC.LineTo( int( Px - 2 * x2 ) ,
                       int( Py - 2 * y2 ) );
      Px = int( Px - 2 * x2 );
      Py = int( Py - 2 * y2 );
    }
    // draw the new polygon
    Px = point.x;
    Py = point.y;
    hyp = sqrt( ( Px - Ox ) * ( Px - Ox ) +
                ( Py - Oy ) * ( Py - Oy ) );
    for ( f = 0;f<m_Sides;f++)
    {
      x1 = hyp * cos( theta );
      mu = atan2( Py - Oy , Px - Ox );
      x2 = x1 * cos( ( mu - theta ) );
      y2 = x1 * sin( ( mu - theta ) );
      ClientDC.MoveTo( int( Px ) , int( Py ) );
      ClientDC.LineTo( int( Px - 2 * x2 ) ,
                       int( Py - 2 * y2 ) );
      Px = int( Px - 2 * x2 );
      Py = int( Py - 2 * y2 );
    }
  }
  PointOld = point;// used to erase the previous drawn figure
  CView::OnMouseMove(nFlags, point);
}

Website : www.mayankmalik.cjb.net

Downloads

Download demo project – 88 Kb
Download source – 25 Kb

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read