1.笔记
1.1绘制多边形函数
BOOL CDC::Polygon(LPPOINT lpPoints,int nCount);
lpPoints是多边形顶点数组名,数组中每个点是CPoint对象(或称POINT结构体),nCount是数组中顶点个数。调用成功返回非零,否则返回零。
1.2阴影画刷
1.2.1创建阴影画刷函数
BOOL CreateHatchBrush(int nIndex,COLORREF crColor);
参数为阴影模式、阴影颜色。调用成功返回非零,否则返回零。
1.2.2阴影模式宏
1.3多边形填充模式
1.3.1设置多边形填充模式
函数原型:
int CDC::SetPolyFillMode(int nPolyFillMode);
调用成功返回原填充模式,否则返回0。
1.3.2填充模式宏
代码 | 宏定义值 |
ALTERNATE | 1 |
WINDING | 2 |
Windows系统的默认填充模式是ALTERNATE。
两种填充模式的具体含义:
(1)ALTERNATE:
该模式使用水平扫描线,遇到交点1开始填充,遇到交点2结束填充,接下来遇到交点3继续填充,遇到交点4结束填充,依此类推……即奇数交点填充开始,偶数交点填充结束。
(2)WINDING:
该模式扫描线从图形内部向外发射,环绕图形,遇到顺时针绘制的边时计数器加1,遇到逆时针绘制的边时计数器减1,计数器不为0时进行填充。
2.使用练习
2.1以圆的五等份点为基础,逐点相连构成五边形,隔点相连构成五角星,五边形是凸多边形,五角星是凹多边形,多边形边界用3像素宽红色实线绘制,多边形内部填充蓝色斜线阴影,在自建坐标系中实现。
需要注意的是,如果从0°开始等分圆,要使多边形相对于客户区是正的,需要旋转调整多边形的顶点再绘制。
编程实现:
void CExample1View::OnDraw(CDC* pDC)
{
CExample1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
CRect rect;
GetClientRect(rect);
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetWindowExt(rect.Width(), rect.Height());
pDC->SetViewportExt(rect.Width(), -rect.Height());
pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);
rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);
int r = 300;
CPoint p[5];//保存位于客户区中心的圆五等份点位置
double theta = 2 * M_PI / 5;//72°,圆五等份角
double alpha = M_PI / 10;//18°=90°-72°,多边形逆时针旋转角度
for (int i = 0; i < 5; ++i) {
p[i].x = (int)(r * cos(i * theta + alpha));
p[i].y = (int)(r * sin(i * theta + alpha));
}
CPoint pentagon[5], pentagram[5];//凸多边形顶点,凹多边形顶点
for (int i = 0; i < 5; ++i) {
pentagon[i].x = p[i].x - rect.Width() / 4;//凸多边形直接向左平移
pentagon[i].y = p[i].y;
}
pentagram[0].x = p[0].x + rect.Width() / 4;//观察得到隔点相连的顺序
pentagram[0].y = p[0].y;
pentagram[1].x = p[2].x + rect.Width() / 4;
pentagram[1].y = p[2].y;
pentagram[2].x = p[4].x + rect.Width() / 4;
pentagram[2].y = p[4].y;
pentagram[3].x = p[1].x + rect.Width() / 4;
pentagram[3].y = p[1].y;
pentagram[4].x = p[3].x + rect.Width() / 4;
pentagram[4].y = p[3].y;
CPen NewPen, * pOldPen;
NewPen.CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
pOldPen = pDC->SelectObject(&NewPen);
CBrush NewBrush, * pOldBrush;
NewBrush.CreateHatchBrush(HS_BDIAGONAL, RGB(0, 0, 255));
pOldBrush = pDC->SelectObject(&NewBrush);
pDC->Polygon(pentagon, 5);
pDC->SetPolyFillMode(WINDING);
pDC->Polygon(pentagram, 5);
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
}
效果: