GDI+ 中绘制弧形文字

该篇博客介绍了在GDI+中如何实现文字沿着圆周排列的两种技术:基本变换方法和路径变换方法。基本变换方法通过计算每个文字的起始角度并进行平移和旋转来实现;路径变换方法则通过获取路径点信息,变换坐标后创建新路径来绘制文字。示例代码详细展示了这两种方法的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

在 GDI+ 中使文字沿着圆周进行排列,有两种实现方法。

使用基本变换方法

①.概述

拆分字符串中的每个文字逐个进行输出,计算出每个文字输出的起始角度,然后分别进行平移变换和旋转变换后输出文字。

②.代码示例

void DemoGDI::DrawUser(HDC hdc)
{
  Graphics graphics(hdc);//构造 Graphics 对象
  Font font(L"宋体", 20, FontStyleRegular, UnitPixel);
  SolidBrush solidBrush(Color::Blue);
  StringFormat stringFormat;
  stringFormat.SetLineAlignment(StringAlignmentCenter);

  PointF cp(200,200);
  Pen m_pen(Color::Black);
  graphics.DrawEllipse(&m_pen, 50, 50, 300, 300);//圆周
  
  graphics.TranslateTransform(cp.X, cp.Y); //平移坐标原点

  QString m_text = "GDI+弧形文字绘制示例";

  float dStepAngle = 20.0f / 150.0f;//每个文字对应的角度:弧长/半径

  int wCount = m_text.toStdWString().size();
  for (int i = 0; i < wCount; i++)
  {
    float dAngle = (i - wCount / 2 + 0.5)*dStepAngle;//与正北方向偏离
    float rAngle = 270 + qRadiansToDegrees(dAngle);//每个文字对应的起始角度
    float a = qDegreesToRadians(rAngle);

    graphics.TranslateTransform(150 * qCos(a), 150 * qSin(a));//平移坐标原点
    graphics.RotateTransform(REAL(rAngle + 90)); // 旋转至切线方向
    graphics.DrawString(m_text.toStdWString().c_str()+i, 1, &font, PointF(-10.0f, -10.0f), &stringFormat, &solidBrush);//输出文字

    graphics.RotateTransform(REAL(-(rAngle + 90))); // 还原 
    graphics.TranslateTransform(-150 * qCos(a), -150 * qSin(a));
  }
}

在这里插入图片描述

使用路径变换方法

①.概述

先获取路径中的点信息,然后变换点的坐标后创建新的路径,用新的路径绘制文本。

②.代码示例

void DemoGDI::DrawUser(HDC hdc)
{
  Graphics graphics(hdc);//构造 Graphics 对象
  SolidBrush solidBrush(Color::Blue);
  
  PointF cp(200,200);
  Pen m_pen(Color::Black);
  graphics.DrawEllipse(&m_pen, 50, 50, 300, 300);//圆周
  graphics.TranslateTransform(cp.X, cp.Y); //平移坐标原点

  GraphicsPath path; //定义路径对象 
  path.AddString(L"GDI+弧形文字绘制示例", -1,&FontFamily(L"黑体"), FontStyleRegular, 25, Point(0, 0), NULL);

  RectF boundRect;
  path.GetBounds(&boundRect);//获取外接矩形 
  Matrix M; //定义单位矩阵
  M.Translate(-(boundRect.X + boundRect.Width / 2),-( boundRect.Y + boundRect.Height));//平移原点到路径的底部中心 
  path.Transform(&M); //更改路径的中心点 

  int n = path.GetPointCount(); // 获取路径中的点数 
  PointF *points = new PointF[n]; // 动态创建点数组 
  path.GetPathPoints(points, n); // 获取路径的点数组
  BYTE *types = new BYTE[n]; // 动态创建类型数组 
  path.GetPathTypes(types, n); // 获取路径类型数组

  for (int i = 0; i < n; i++) //根据路径点到中心的距离,按比例修改点的 y 值 
  {
    points[i].Y -= sqrt(150*150 - points[i].X*points[i].X);  
  }
  
  GraphicsPath newPath(points, types, n); //用新的路径点构造新路径
  graphics.FillPath(&SolidBrush(Color::Green), &newPath);//填充路径

}

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值