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



Comments

  • guter Beitrag

    Posted by Pybristeburry on 10/30/2012 10:57pm

    Jack Wolfskin Jacket,a4ou30, Jack Wolfskin Sale,j3ef86, Jack Wolfskin Online Shop,c8lq67, Jack Wolfskin,g2qe56,

    Reply
  • guter Beitrag

    Posted by aquantispumus on 10/30/2012 10:56pm

    Jack Wolfskin Sale,y3qr13, Jack Wolfskin Jacket,a7dn44, Jack Wolfskin Outlet,h6ty32, Jack Wolfskin,z1uv01,

    Reply
  • guter Beitrag

    Posted by aquantispumus on 10/30/2012 10:55pm

    Jack Wolfskin Sale,a4pn39, Jack Wolfskin Online Shop,r5nt81, Jack Wolfskin Jacket,j1bu24, Jack Wolfskin,g5eb11,

    Reply
  • guter Beitrag

    Posted by ClermFloomb on 10/30/2012 10:55pm

    Jack Wolfskin Jacket,o8pv63, Jack Wolfskin,r1ur77, Jack Wolfskin Sale,e9vu83, Jack Wolfskin Outlet,f1xc36,

    Reply
  • guter Beitrag

    Posted by phochehak on 10/30/2012 10:54pm

    Jack Wolfskin,v9uw89, Jack Wolfskin Outlet,z5zf13, Jack Wolfskin Online Shop,g4lb05, Jack Wolfskin Jacket,z9vf45,

    Reply
  • http://www.ucancode.net

    Posted by Legacy on 08/01/2003 12:00am

    Originally posted by: MFC Diagramming Library with Source Code!

    Great!!

    Reply
  • Speedup

    Posted by Legacy on 06/17/2003 12:00am

    Originally posted by: Alex

    One smart optimisation ( from the old days): Divide the XY area in 8 octants( or hexants,or whatever is the decomposition of N in prime factors). Compute the vertices for one and flip/mirror for th others. This will solve partially the problem of rounding and also speed up a lot the code.


    The code is very interesting.

    Alex

    Reply
  • Alternate Code

    Posted by Legacy on 07/17/2002 12:00am

    Originally posted by: DjinnKahn

    replace the given code snippet with this:
    
    


    void Draw(CClientDC& dc, CPoint orig, CPoint vertex, int iNumSides)
    {
    vertex -= orig;
    for (int i = 0; i <= iNumSides; i++) {
    double fCos = cos(i * 4*acos(0)/iNumSides);
    double fSin = sin(i * 4*acos(0)/iNumSides);
    CPoint p( int(vertex.x * fCos - vertex.y * fSin + .5),
    int(vertex.x * fSin + vertex.y * fCos + .5));
    if (i) dc.LineTo(p + orig);
    dc.MoveTo(p + orig);
    }
    }

    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);// INITIALIZE GRAPHICS
    ClientDC.SetROP2(R2_NOT);
    Draw(ClientDC, PointOrigin, PointOld, m_Sides);
    Draw(ClientDC, PointOrigin, point, m_Sides);
    }
    PointOld = point;// used to erase the previous drawn figure
    CView::OnMouseMove(nFlags, point);
    }

    Reply
  • S.O.S

    Posted by Legacy on 09/17/2001 12:00am

    Originally posted by: Samy

    Can anyone help me please?
    To generate a form,

    I want to draw "N" rectangle and lines in my GDI and for each rectangle I need to gave a name and save all properties (X1,Y1,X2,Y2) in text file.
    Each line must be resizable and tracking(I don't know haw to track a line).
    Each rectangle must be resizable and tracking(I already do this with one rectangle).
    Each rectangle must be able to receive a text(I already do this with one rectangle).
    The properties of each text in rectangle must be interactive changed by user and also saved in text file(I already do this using LbuttonDblclick + fontdialog).

    For example:
    Myfile.txt
    Rectangle name: X1: Y1: X2: Y2: fontsize: fontname:

    Title 100 120 200 220 12 Arial
    Adres 150 200 200 250 10 Currier
    .....

    It is posible to decide that I have i.e 10 elements. In this case I must initalize all of them and drawing one to one.
    But in this case user will not have any flexibility to add new rectangle any time when he want.

    Could any one gave me some good algoritm for that?
    Best regards,
    Samuel

    Reply
  • Rounding-problem ? no problem

    Posted by Legacy on 08/22/2001 12:00am

    Originally posted by: Dieter Hammer

    in th loop You have only to remove the (int) casts, that's all folks!
    Px = Px - 2 * x2 ;
    Py = Py - 2 * y2 ;

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: September 10, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild". This loop of continuous delivery and continuous feedback is …

  • Best-in-Class organizations execute on a strategy that supports the multi-channel nature of customer requests. These leading organizations do not just open up their service infrastructures to accommodate new channels, but also empower their teams to deliver an effective and consistent experience regardless of the channel selected by the customer. This document will highlight the key business capabilities that support a Best-in-Class customer engagement strategy.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds