首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

用GDI+旋转多边形来绘制一个时钟摸拟小程序

编程知识
2024年08月22日 12:57

效果图

 

在头文件类中声明变量

TCHAR m_dayStr[4];    // 日期
    TCHAR m_weekStr[4];  // 星期
    Gdiplus::Font* m_pFont;  // 字体
    Gdiplus::StringFormat m_strFormat;  // 格式化字符串
    Gdiplus::Pen* m_pPen;      // 画笔
    Gdiplus::SolidBrush* m_pBrush;  // 画刷
    Gdiplus::RectF m_dayRect;      // 日期矩形
    Gdiplus::RectF m_weekRect;      // 星期矩形
    Gdiplus::PointF m_orgPointF; // 圆点坐标
    float m_rColok;    //圆半径

  Gdiplus::PointF hourPts[4];  //时针多边形数组
  Gdiplus::PointF mimPts[4];    //分针多边形数组
  Gdiplus::PointF scrPts[2];    //秒针数组

 

 

在初始化函数中初始变量的值

// 获得系统时间
SYSTEMTIME sysTime;
GetLocalTime(&sysTime);

// 格式化日期和星期字符串
_stprintf_s(m_dayStr,TEXT("%02d"),sysTime.wDay);

TCHAR weekStrs[7][4]={L"",L"",L"",L"",L"",L"",L""};
_stprintf_s(m_weekStr,TEXT("%s"),weekStrs[sysTime.wDayOfWeek]);

// 启动时间计时器
SetTimer(m_hWnd,11,1000,NULL);

在WM_SIZE中计算圆点,半径,多边形分针,时针,秒针的顶点坐标数组值

float cx=LOWORD(lParam);
    float cy=HIWORD(lParam);

        // 计算圆点
    m_orgPointF.X=cx/2;
    m_orgPointF.Y=cy/2;
        
        // 计算半径
    m_rColok=min(cx,cy)/2;
    m_rColok-=10;

    float r=m_rColok;
    
        // 秒针数组赋值
    scrPts[0].X=0;
    scrPts[0].Y=-r*9/10;
    scrPts[1].X=0;
    scrPts[1].Y=r*2/10;

    // 分针多边形坐标数组
    mimPts[0].X=(float)(-r*0.7 / 10);
    mimPts[0].Y=0;
    mimPts[1].X=0;
    mimPts[1].Y=-r * 8/ 10;
    mimPts[2].X=(float)(r*0.7 / 10);
    mimPts[2].Y=0;
    mimPts[3].X=0;
    mimPts[3].Y=r * 2/ 10;

    // 时针多边形数组
    hourPts[0].X=-r / 10;
    hourPts[0].Y=0;
    hourPts[1].X=0;
    hourPts[1].Y=-r * 6/ 10;
    hourPts[2].X=r / 10;
    hourPts[2].Y=0;
    hourPts[3].X=0;
    hourPts[3].Y=r * 2/ 10;

        // 日期矩形
    m_dayRect.X=r-16;
    m_dayRect.Y=-10;
    m_dayRect.Width=20;
    m_dayRect.Height=20;

        // 日期矩形
    m_weekRect.X=r-36;
    m_weekRect.Y=-10;
    m_weekRect.Width=20;
    m_weekRect.Height=20;    

 

 

用旋转图片来绘制多边形,

图片旋转是以圆点为中心来旋转的,

所以要重新设置坐标系圆点为表盘中心点

自定义函数RotatePolygon来计算多边形的旋转,和绘制

// 旋转多边形,并绘制
// (绘制对象,多边形顶点坐标数组,顶点个数,旋转角度)
void
RotatePolygon(Gdiplus::Graphics* graphics, Gdiplus::PointF* points, int numPoints, float angle) { // 创建旋转矩阵 Gdiplus::Matrix matrix; matrix.Rotate(angle); // 旋转多边形的每个点 Gdiplus::PointF* rotatedPoints = new Gdiplus::PointF[numPoints]; for (int i = 0; i < numPoints; i++) { Gdiplus::PointF point = points[i]; matrix.TransformPoints(&point, 1); rotatedPoints[i] = point; } Gdiplus::Pen pen(Color(255,0,0,0),(numPoints==2) ? 2.0f:1.0f); // 绘制旋转后的多边形 graphics->DrawPolygon(&pen, rotatedPoints, numPoints);
  
  
  // 用线性渐变画刷填充多边形 graphics
->FillPolygon(&Gdiplus::LinearGradientBrush(rotatedPoints[0],rotatedPoints[2], Color(255,0,0,255),Color(255,255,255,0)),rotatedPoints,numPoints); delete[] rotatedPoints; }

最后在WM_PAINT消息中绘制

void MyMainWnd::OnPaint(){

    PAINTSTRUCT ps;
    HDC hdc=BeginPaint(m_hWnd,&ps);

    // 创建内存dc,创建内存位图,并将内存位图选入内存dc中
    HDC hmdc=CreateCompatibleDC(hdc);;
    HBITMAP hBitmap=CreateCompatibleBitmap(hdc,ps.rcPaint.right,ps.rcPaint.bottom);
    HGDIOBJ hOldMap=SelectObject(hmdc,hBitmap);

    // 创建在内存dc中绘图对象
    Gdiplus::Graphics g(hmdc);
    g.SetSmoothingMode(SmoothingModeAntiAlias); //设置抗锯齿模式
    

    // 用指定颜色填充整个内存位图
    m_pBrush->SetColor(Color(255,128,128,129));
    g.FillRectangle(m_pBrush,0,0,ps.rcPaint.right,ps.rcPaint.bottom);

    // 设置新的坐标系原点为表盘中心点
    Gdiplus::Matrix transform;
    transform.Translate(m_orgPointF.X, m_orgPointF.Y);
    g.SetTransform(&transform);


    float xBegin,yBegin;
    float rClock=m_rColok; // 圆的半径

    // 用指定颜色的画刷,绘制表盘上的刻度
    m_pBrush->SetColor(Color(255,217,222,18));
    for(int i=0;i<60;i++)
    {
        xBegin = (float)( rClock * sin(2 * PI*i / 60));
        yBegin = (float)(rClock * cos(2 * PI*i / 60));

        if (i % 5)
        {
            // 填充小圆点表示小刻度
            g.FillEllipse(m_pBrush,xBegin-2,yBegin-2,4.0f,4.0f);
        }
        else
        {
            // 填充大圆点表示大刻度
            g.FillEllipse(m_pBrush,xBegin-4,yBegin-4,8.0f,8.0f);
        }
    }

    //获取系统时间
    SYSTEMTIME x;
    GetLocalTime(&x);

    // 绘制显示日期和星期的矩形区域
    m_pPen->SetColor(Color::Black);
    m_pBrush->SetColor(Color::YellowGreen);
    g.DrawRectangle(m_pPen,m_dayRect);
    g.DrawRectangle(m_pPen,m_weekRect);
    g.FillRectangle(m_pBrush,m_dayRect);
    g.FillRectangle(m_pBrush,m_weekRect);

    // 绘制日期和星期的字符串文本
    m_pBrush->SetColor(Color::Black);
    g.DrawString(m_dayStr,-1,m_pFont,m_dayRect,&m_strFormat,m_pBrush);
    g.DrawString(m_weekStr,-1,m_pFont,PointF(m_weekRect.X+1,m_weekRect.Y+4),m_pBrush);

    // 绘制时针
    float tem=(float)((float)x.wMinute/60);
    float fHour=x.wHour+tem;
    float sita=float(fHour*30);
    RotatePolygon(&g,hourPts,4,(float)sita); //计算时针旋转角度并绘制

    // 绘制分针
    sita=float(x.wMinute*6);
    RotatePolygon(&g,mimPts,4,(float)sita);

    // 绘制秒针
    sita = float(x.wSecond*6);
    RotatePolygon(&g,scrPts,2,sita);

    // 绘制圆心
    m_pBrush->SetColor(Color(255,0,0,255));
    g.FillEllipse(m_pBrush,-6,-6,12,12);

    // 将内存dc中绘制的图片复制到当前dc中
    BitBlt(hdc,0,0,(int)ps.rcPaint.right,(int)ps.rcPaint.bottom,hmdc,0,0,SRCCOPY);

    // 释放内存位图,内存dc
    SelectObject(hmdc,hOldMap);
    DeleteObject(hBitmap);
    DeleteObject(hmdc);

    EndPaint(m_hWnd,&ps);
}

 

From:https://www.cnblogs.com/greenleaf1976/p/18373696
本文地址: http://shuzixingkong.net/article/1335
0评论
提交 加载更多评论
其他文章 MySQL 亿级数据平滑迁移实战
本文介绍了一次 MySQL 数据迁移的流程,通过方案选型、业务改造、双写迁移最终实现了亿级数据的迁移。
MySQL 亿级数据平滑迁移实战 MySQL 亿级数据平滑迁移实战 MySQL 亿级数据平滑迁移实战
Python开发中,SQLAlchemy 的同步操作和异步操作封装,以及常规CRUD的处理。
在我们使用Python来和数据库打交道中,SQLAlchemy是一个非常不错的ORM工具,通过它我们可以很好的实现多种数据库的统一模型接入,而且它提供了非常多的特性,通过结合不同的数据库驱动,我们可以实现同步或者异步的处理封装。
Python开发中,SQLAlchemy 的同步操作和异步操作封装,以及常规CRUD的处理。
IoTSharp:基于 .NET 8.0 的开源物联网平台
前言 想要快速了解物联网的世界吗?如果你对物联网(IoT)感兴趣,或者正打算开发自己的物联网项目。可以试试 IoTSharp,一个基于 .NET 的开源平台。 无论你是初学者还是有经验的大佬,IoTSharp 提供了丰富的功能和广泛的协议支持。让物联网项目开发变得简单又直观。它不仅功能全面,而且操作
IoTSharp:基于 .NET 8.0 的开源物联网平台 IoTSharp:基于 .NET 8.0 的开源物联网平台 IoTSharp:基于 .NET 8.0 的开源物联网平台
Figma 替代品 Penpot 安装和使用教程
在设计领域,Figma 无疑是一个巨人。它彻底改变了设计流程,将协作带到了一个全新的高度。然而,随着 Adobe 收购 Figma 的消息传出,许多设计师和开发者开始担心:Figma 未来会如何演变?那些好用的特性会不会被砍掉? 出于白嫖的本能,大家都想寻找一个强大而可靠的 Figma 替代品。在众
Figma 替代品 Penpot 安装和使用教程 Figma 替代品 Penpot 安装和使用教程 Figma 替代品 Penpot 安装和使用教程
小红书分享踩坑和解决
​小红书官方介入链接:小红书分享开放平台 下载sdk文件,位置如下图所示 之后可以按照官方文档进行开发,接入也较简单,这里主要是说明一些隐藏的坑点 一、分享应用内的文件到小红书(这里主要是指应用包名下的文件内容),需要注意setFileProviderAuthority()这个方法。 例如我的代码如
小红书分享踩坑和解决 小红书分享踩坑和解决
使用SiliconCloud快速体验SimpleRAG(手把手教程)
SiliconCloud介绍 SiliconCloud 基于优秀的开源基础模型,提供高性价比的 GenAI 服务。 不同于多数大模型云服务平台只提供自家大模型 API,SiliconCloud上架了包括 Qwen、DeepSeek、GLM、Yi、Mistral、LLaMA 3、SDXL、Instan
使用SiliconCloud快速体验SimpleRAG(手把手教程) 使用SiliconCloud快速体验SimpleRAG(手把手教程) 使用SiliconCloud快速体验SimpleRAG(手把手教程)
kubeadm升级k8s之1.23.17->1.24.17
查看当前版本 [root@k8s-master31 ~]# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIM
Linux-mknod命令
mknod 创建块设备或者字符设备文件。此命令的适用范围:RedHat、RHEL、Ubuntu、CentOS、SUSE、openSUSE、Fedora。 用法: mknod [选项]... 名称 类型 [主设备号 次设备号] 选项参数列表: 选项 说明 --version 显示命令版本信息 --he