生成美观的线条样式






4.40/5 (6投票s)
一种创建复杂线条图案的新颖方法
引言
这项技术是一种创新的生成美观线型的方式。它主要用于 CAD/GIS 及相关应用,这些应用需要自定义线型。它完全使用 MFC 编写,并且非常易于使用。
背景
我一直在研究如何创建自定义线型。我生成此类线型的努力包括:
- 使用矢量图形沿给定线布置。这涉及到复杂的矩阵数学。但它效率低下,无法应用于填充的几何实体。
- 使用分形几何,这也证明是不明智的,因为它需要为我感兴趣的每种线条图案发明一个新公式。
- 我偶然发现了一个使用 LineDDA 的文章来生成复杂的线型,该文章涉及使用回调函数来绘制复杂的线型。此技术是 Win32 解决方案,目前不直接受 MFC 支持。尽管它是一个出色的解决方案,但它并非万无一失,我得到了不理想的输出。例如,当我选择字符“X”作为线条图案的输入时,输出如下:(图 1 & 2)。
![]() |
![]() |
图 1. 理想的输出
|
图 2. 错误的输出
|
这促使我致力于开发一种更简单、更优雅、不会给普通程序员增加智力负担的 MFC 解决方案。我使用了 TrueType(.ttf)字体来生成线型。字体中的每个 字形 都可以用作线条的图案。
技巧

使用 Microsoft 的字符映射应用程序(开始 > 所有程序 > 附件 > 系统工具 > 字符映射)并从所需的字体中选择一个字符或符号(代表您的线型的图案)。每个符号都有一个唯一的十六进制数字与之关联。我们在逻辑中使用这个十六进制数字。上面图像中突出显示的符号的十六进制数字是 0x5C。请参见图 3。
注意:我计划通过使用此网站上Hans Dietrich撰写的文章《XCharMap - 用于显示字符映射的对话框》中的代码来扩展此应用程序。
您可以使用 CorelDraw、Font Creator 或 Fontlab 等字体创建工具,设计自己的 TrueType 字体符号图案。将您创建的字体复制到 Windows 目录的Fonts文件夹中。这可以通过进入控制面板中的Fonts文件夹来完成。
理解代码
我采用了 Jeff Prosise 的《Programming Windows with MFC》第三章中绘制橡皮筋线的代码,此处不再赘述。核心逻辑在视图类的OnLButtonUp
中。
要沿着绘制的线布置所需的图案,首先,计算线的斜率以及线相对于水平线的夹角。
//calculate the slope of this line
if(point.x-m_ptFrom.x==0) return;//Avoid crashes due to infinity
float slope= -(point.y -m_ptFrom.y)/(point.x-m_ptFrom.x);
//Negative sign is used as the slope from math.h is in clockwise direction, while the
//LOGFONT expects angle in counter-clockwise direction.
//find the inclination w.r.t horizontal
float ang=atan2(m_ptFrom.y-point.y,point.x-m_ptFrom.x)*180.0f/3.1415927f;
将角度分配给LOGFONT
变量的 Orientation 和 Escapement 属性。选择感兴趣的字体,并将字符/符号的十六进制值赋给CString
变量。
LOGFONT lf;
lf.lfCharSet=SYMBOL_CHARSET;//For Symbol Fonts like "Wingdings"
lf.lfHeight=20;
lf.lfEscapement=(long)ang*10;//Angle of the text
lf.lfOrientation=(long)ang*10;//Angle of the text
lf.lfItalic=false;
lf.lfStrikeOut=false;
lf.lfUnderline=false;
lf.lfQuality=ANTIALIASED_QUALITY;
lf.lfWeight=FW_BOLD;
strcpy(lf.lfFaceName,_T("Wingdings"));//Select the desired font
--
--
--
CString str;
str=0x5c;//Hexadecimal value of the desired //character/symbol from Character Map
找到线段的长度,并重复地将字符/符号的十六进制值添加到CString
变量中,直到string
的宽度小于线的长度。绘制文本,我们就得到了惊人的线条图案。
//Calculate Length of line segment in pixels
float dist= sqrt((point.y - m_ptFrom.y )*(point.y-m_ptFrom.y )+
(point.x-m_ptFrom.x)*(point.x-m_ptFrom.x)) ;
//Add Symbol to the text until the width of string is less than length of line
while(textwidth < dist )
{
str+=0x5c;
textwidth=dc.GetTextExtent(str).cx;
}
运行应用程序
在 VS6 中编译源代码并生成它(或)使用AestheticLines_Demo.zip中的可执行文件。单击并拖动以绘制橡皮筋线。请注意,通过简单地颠倒绘制顺序,我们可以获得反转的符号。请参见下面的图 4。

进一步改进
- 从应用程序中调用的字符映射对话框中选择所需的符号。(我将就此与Hans Dietrich联系。)
- 扩展绘图逻辑,使用户能够绘制折线图和多边形。
- 提供一个对话框,用于选择字体大小、颜色、对齐方式等。
参考文献
- www.microsoft.com/typography/
- http://www.codeguru.com/cpp/g-m/gdi/article.php/c135/
- Programming Visual C++ 6.0, Kruglinski
- Jeff Prosise, Programming Windows with MFC, Second Edition Microsoft Press, 1999
致谢
- Pravin Ramdas Raijade
历史
- 2008年4月6日:首次发布
我希望这篇文章有用。请随意扩展、修复错误和改进它。如果您能在您的程序或文档中注明我,那将是很好的。