MFC之学习多边形绘制、阴影模式、多边形填充模式与绘制实心五角星

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填充模式宏

代码宏定义值
ALTERNATE1
WINDING2

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);
}

效果:

  • 4
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要实现交互式多边形绘制,可以在鼠标左键按下、移动和松开的事件响应函数中分别处理。 首先,在鼠标左键按下事件响应函数中,创建一个新的多边形对象,将鼠标当前位置作为多边形的第一个顶点,并将该顶点添加到多边形的顶点列表中。然后,开始捕捉鼠标移动事件。 在鼠标移动事件响应函数中,获取当前鼠标位置,并将其作为多边形的下一个顶点,更新多边形的顶点列表。同时,使用CDC类的Polyline函数将多边形的边实时绘制出来。 最后,在鼠标左键松开事件响应函数中,结束多边形绘制,并将多边形对象添加到文档中。 下面是一个示例代码: ```cpp void CMyView::OnLButtonDown(UINT nFlags, CPoint point) { // 创建新的多边形对象 CPolygon polygon; polygon.AddVertex(point); // 添加多边形到文档中 CMyDoc* pDoc = GetDocument(); pDoc->AddPolygon(polygon); // 捕捉鼠标移动事件 SetCapture(); } void CMyView::OnMouseMove(UINT nFlags, CPoint point) { // 获取文档中的最后一个多边形对象 CMyDoc* pDoc = GetDocument(); CPolygon& polygon = pDoc->GetLastPolygon(); // 更新多边形的顶点列表 polygon.AddVertex(point); // 在设备上下文中绘制多边形的边 CDC* pDC = GetDC(); pDC->SelectStockObject(NULL_BRUSH); pDC->Polyline(polygon.GetPoints(), polygon.GetVertexCount()); ReleaseDC(pDC); } void CMyView::OnLButtonUp(UINT nFlags, CPoint point) { // 结束捕捉鼠标移动事件 ReleaseCapture(); } ``` 上面的代码使用了CPolygon类来表示多边形对象。CPolygon类的实现可以参考下面的代码: ```cpp class CPolygon { public: void AddVertex(const CPoint& point) { m_points.push_back(point); } const CPoint* GetPoints() const { return m_points.data(); } int GetVertexCount() const { return static_cast<int>(m_points.size()); } private: std::vector<CPoint> m_points; }; ``` 注意,上面的代码中使用了STL的vector容器来存储多边形的顶点列表。如果您不想使用STL,可以使用数组或链表等其它数据结构来实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赴星辰大海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值