Drawing any N-sided Polygon



Click here for larger image

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