GDI Topics:  Polylines

 

Introduction

A polyline is a series of connected lines. The lines are stored in an array of POINT or CPoint values. To draw a polyline, you use the CDC::Polyline() method. Its syntax is:

BOOL Polyline(LPPOINT lpPoints, int nCount);

The lpPoints argument is an array of points that can be of POINT or CPoint types. The nCount argument specifies the number of members of the array. When executing, the compiler moves the starting point to lpPoints[0]. The first line is drawn from lpPoints[0] to lpPoints[1] as in:

void CExoView::OnDraw(CDC* pDC)
{
	CPoint Pt[] = { CPoint(60, 20), CPoint(60, 122) };
	pDC->MoveTo(Pt[0]);
	pDC->LineTo(Pt[1]);
}

To draw a polyline, you must have at least two points. If you define more than two points, each line after the first would be drawn from the previous point to the next point until all points have been included. Here is an example:

void CExoView::OnDraw(CDC* pDC)
{
	CPoint Pt[7];
	Pt[0] = CPoint(20, 50);
	Pt[1] = CPoint(180, 50);
	Pt[2] = CPoint(180, 20);
	Pt[3] = CPoint(230, 70);
	Pt[4] = CPoint(180, 120);
	Pt[5] = CPoint(180, 90);
	Pt[6] = CPoint(20, 90);

	pDC->Polyline(Pt, 7);
}
Polyline

Besides the Polyline() method, the CDC class provides the PolylineTo() member function. Its syntax is:

BOOL PolylineTo(const POINT* lpPoints, int nCount);

The lpPoints argument is the name of an array of POINT or CPoint objects. The nCount argument specifies the number of points that would be included in the figure. Here is an example:

void CExoView::OnDraw(CDC* pDC)
{
	CPoint Pt[7];

	Pt[0] = CPoint(20, 50);
	Pt[1] = CPoint(180, 50);
	Pt[2] = CPoint(180, 20);
	Pt[3] = CPoint(230, 70);
	Pt[4] = CPoint(180, 120);
	Pt[5] = CPoint(180, 90);
	Pt[6] = CPoint(20, 90);

	pDC->PolylineTo(Pt, 7);
}
Polyline To

While the Polyline() method starts the first line at lpPoints[0], the PolylineTo() member function does not control the beginning of the first line. Like the LineTo() method, it simply starts drawing, which would mean it starts at the origin (0, 0). For this reason, if you want to control the starting point of the PolylineTo() drawing, you can use the MoveTo() method:

void CExoView::OnDraw(CDC* pDC)
{
	CPoint Pt[7];

	Pt[0] = CPoint(20, 50);
	Pt[1] = CPoint(180, 50);
	Pt[2] = CPoint(180, 20);
	Pt[3] = CPoint(230, 70);
	Pt[4] = CPoint(180, 120);
	Pt[5] = CPoint(180, 90);
	Pt[6] = CPoint(20, 90);

	pDC->MoveTo(20, 30);
	pDC->PolylineTo(Pt, 7);
	pDC->LineTo(20, 110);
}
Polyline To with controlled origin

Practical Learning:  Drawing Polylines

  1. To draw a polyline, change the event as follows:
     
    void CView1View::OnPaint() 
    {
    	CPaintDC dc(this); // device context for painting
    	
    	// TODO: Add your message handler code here
    	CPoint PtLine[] = { CPoint( 50,  50), CPoint(670,  50),
    			  CPoint(670, 310), CPoint(490, 310),
    			  CPoint(490, 390), CPoint(220, 390),
    			  CPoint(220, 310), CPoint( 50, 310), 
    			  CPoint( 50,  50) };
    	CPoint PlLine[] = { CPoint( 55,  55), CPoint(665,  55),
    			  CPoint(665, 305), CPoint(485, 305),
    			  CPoint(485, 385), CPoint(225, 385),
    			  CPoint(225, 305), CPoint( 55, 305),
    			  CPoint(55, 55) };
    
    	dc.MoveTo(PtLine[0]);
    	dc.LineTo(PtLine[1]);
    	dc.LineTo(PtLine[2]);
    	dc.LineTo(PtLine[3]);
    	dc.LineTo(PtLine[4]);
    	dc.LineTo(PtLine[5]);
    	dc.LineTo(PtLine[6]);
    	dc.LineTo(PtLine[7]);
    	dc.LineTo(PtLine[8]);
    
    	dc.Polyline(PlLine, 9);
    	// Do not call CView::OnPaint() for painting messages
    }
  2. Test the application

Multiple Polylines

The above polylines were used each as a single entity. That is, a polyline is a combination of lines. If you want to draw various polylines in one step, you can use the CDC::PolyPolyline() method. By definition, the PolyPolyline() member function is used to draw a series of polylines. Its syntax is:

BOOL PolyPolyline(const POINT* lpPoints, const DWORD* lpPolyPoints, int nCount);

Like the above Polyline() method, the lpPoints argument is an array of POINT or CPoint values. The PolyPolyline() method needs to know how many polylines you would be drawing.  Each polyline will use the points of the lpPoints value but when creating the array of points, the values must be incremental. This means that PolyPolyline() will not access their values at random. It will retrieve the first point, followed by the second, followed by the third, etc. Therefore, your first responsibility is to decide where one polyline starts and where it ends. The good news (of course depending on how you see it) is that a polyline does not start where the previous line ended. Each polyline has its own beginning and its own ending point. 

Unlike Polyline(), here, the nCount argument is actually the number of shapes you want to draw and not the number of points (remember that each polyline "knows" or controls its beginning and end).

The lpPolyPoints argument is an array or positive integers (unsigned long). Each member of this array specifies the number of vertices (lines) that its corresponding polyline will have. For example, imagine you want to draw M, followed by L, followed by Z. The letter M has 4 lines but you need 5 points to draw it. The letter L has 2 lines and you need 3 points to draw it. The letter Z has 3 lines so 4 points are necessary to draw it. You can store this combination of lines in an array defined as { 5, 3, 4 }.

Here is an example:

void CExoView::OnDraw(CDC* pDC)
{
	CPoint Pt[15];
	DWORD  lpPts[] = { 4, 4, 7 };

	// Left Triangle
	Pt[0] = Pt[3] = CPoint(50, 20);
	Pt[1] = CPoint(20, 60);
	Pt[2] = CPoint(80, 60);
	
	// Second Triangle
	Pt[4] = Pt[7] = CPoint(70, 20);
	Pt[5] = CPoint(100, 60);
	Pt[6] = CPoint(130, 20);

	// Hexagon
	Pt[8]  = Pt[14] = CPoint(145, 20);
	Pt[9]  = CPoint(130, 40);
	Pt[10] = CPoint(145, 60);
	Pt[11] = CPoint(165, 60);
	Pt[12] = CPoint(180, 40);
	Pt[13] = CPoint(165, 20);

	pDC->PolyPolyline(Pt, lpPts, 3);
}
PolyPolyline

 

 

Home Copyright © 2003-2004 FunctionX, Inc.