C#基于SkiaSharp实现印章管理(5)

  印章中最常见的特殊形状通常是五角星,空心、实心的都可能存在,本文学习并实现在印章内部绘制五角星形状。
  百度五角星的绘制方法,主要分为三种:
  1)五角星各点坐标固定,直接调用编程语言的绘制线条或绘制多边形的函数绘制五角星;
  2)利用编程语言中的旋转变换方式简化五角星绘图逻辑,如Python中的turtle模块,绘制五角星时就是绘直线->转向->绘直线,C#的GDI+和SkiaSharp模块都支持旋转变换,但相对Python而言则复杂得多;
  3)利用公式计算各点坐标,以五角星中某点为基准,计算其余九个点的坐标,然后调用编程语言的绘制线条或绘制多边形的函数绘制五角星。
  本文选择第三种方式,使用参考文献4中的计算公式计算各点坐标,下图也来自参考文献4。

  更新FigureType枚举,增加五角星类型,同时调整SealElement定义,为了与后续绘制文本时保持一致,增加Content字符串属性,将五角星10个点的坐标以特定格式保存在Content属性中,并在绘图时解析、绘制。
  创建新建五角星窗口(如下图所示),使用StartPoint属性保存起点坐标,用EndPoint的X属性保存五角星边长,其它设置保持不变。点击确定时基于参考文献4的计算公式计算各点坐标,不过测试过程中发现公式并不完全正确,使用基于公式计算参考文献2的各点坐标时个别点的坐标计算公式有误(F、G,同时各点的Y坐标都没有加起始点的Y坐标值),最终各点坐标计算方式如下代码所示:

csharp 复制代码
double angle18 = 18 * Math.PI / 180;
double angle36 = 36 * Math.PI / 180;
float sinValue = Convert.ToSingle(Math.Round(Math.Sin(angle18), 2));
float cosValue = Convert.ToSingle(Math.Round(Math.Cos(angle18), 2));
float sinValueLong36 = Convert.ToSingle(Math.Round(Math.Sin(angle36) * m_element.EndPoint.X, 2));
float cosValueLong36 = Convert.ToSingle(Math.Round(Math.Cos(angle36) * m_element.EndPoint.X, 2));
float sinValueLong = Convert.ToSingle(Math.Round(sinValue *m_element.EndPoint.X));
float cosValueLong = Convert.ToSingle(Math.Round(cosValue * m_element.EndPoint.X));
float sinValueLong2 = 2 * sinValueLong;
float cosValueLong2 = 2 * cosValueLong;

StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append($"{m_element.StartPoint.X},{m_element.StartPoint.Y};");//A
stringBuilder.Append($"{m_element.StartPoint.X+ sinValueLong},{m_element.StartPoint.Y+ cosValueLong};");//C
stringBuilder.Append($"{m_element.StartPoint.X + sinValueLong + m_element.EndPoint.X},{m_element.StartPoint.Y + cosValueLong};");//E
stringBuilder.Append($"{m_element.StartPoint.X + sinValueLong+m_element.EndPoint.X-cosValueLong36},{m_element.StartPoint.Y + cosValueLong+ sinValueLong36};");//G
stringBuilder.Append($"{m_element.StartPoint.X + sinValueLong2*sinValue + sinValueLong2},{m_element.StartPoint.Y + sinValueLong2 * cosValue + cosValueLong2};");//I
stringBuilder.Append($"{m_element.StartPoint.X},{m_element.StartPoint.Y+cosValueLong2+sinValueLong2*cosValue-sinValueLong36};");//J
stringBuilder.Append($"{m_element.StartPoint.X - sinValueLong2 * sinValue - sinValueLong2},{m_element.StartPoint.Y + sinValueLong2 * cosValue + cosValueLong2};");//H
stringBuilder.Append($"{m_element.StartPoint.X - sinValueLong - m_element.EndPoint.X+ cosValueLong36},{m_element.StartPoint.Y + cosValueLong + sinValueLong36};");//F
stringBuilder.Append($"{m_element.StartPoint.X-sinValueLong-m_element.EndPoint.X},{m_element.StartPoint.Y+cosValueLong};");//D
stringBuilder.Append($"{m_element.StartPoint.X-sinValueLong},{m_element.StartPoint.Y+cosValueLong};");//B
stringBuilder.Append($"{m_element.StartPoint.X},{m_element.StartPoint.Y}");//A

  绘制五角星时,最初采用canvas.DrawPoints函数,但测试时发现无论SKPaint的Style设置为Stroke或Fill,显示时都是按边框方式显示,暂时不清楚怎么回事,最终换为先创建SKPath,再调用AddPoly添加形状,最终调用canvas.DrawPath绘制形状的方式解决问题。
  最后是程序运行效果,包括显示边框和填充两种方式:

参考文献:

1https://learn.microsoft.com/zh-cn/dotnet/api/skiasharp?view=skiasharp-2.88

2https://www.cnblogs.com/bhnian/p/16343557.html

3https://www.jb51.net/html5/676291.html

4https://blog.csdn.net/L_Shaker/article/details/127313457

5https://blog.csdn.net/qq_42716155/article/details/105024837

相关推荐
XiaoZhenHua981 天前
C#工业机器视觉Recipe配方系统设计:多型号、多相机、多工位参数如何统一管理
c#·软件架构·机器视觉·工业自动化·工业软件·recipe
fujisheng6611 天前
FUI 导航实践:拆开 Layer、History、Coverage 与 Cache 的组合语义
c#·unity3d
淡海水1 天前
10-05-高级-模式匹配-CSharp如何改变与数据结构的交互方式
数据结构·算法·c#·模式匹配
XiaoZhenHua981 天前
C# WinForms + 西门子S7 + SQLite + EPPlus生产数据采集系统架构设计
系统架构·sqlite·c#
Lost of 程序猿1 天前
船岸数据同步链路实战:SendFlag、单调版本号与断网三天后的续传
后端·c#·asp.net
cjp5602 天前
012.UG二次开发,UG管道服务器与WPF管道通讯,传输JSON数据
c#
jiushidt2 天前
ArcGIS Pro Add‑in 打包流程详解
arcgis·c#·.net·arcgispro
geovindu3 天前
CSharp: Observer Pattern
开发语言·后端·观察者模式·设计模式·c#·.netcore·行为模式
软件黑马王子3 天前
20.Resources资源加载:基本实现
开发语言·前端框架·c#
张人玉3 天前
基于 C# / .NET 8 + Windows Forms + SQLite 的桌面银行业务演示系统——华夏示范银行管理系统
windows·sqlite·c#·.net