65.9K
CodeProject 正在变化。 阅读更多。
Home

生成美观的线条样式

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.43/5 (5投票s)

2008年4月10日

CPOL

3分钟阅读

viewsIcon

30395

downloadIcon

607

这主要适用于 CAD/GIS 及相关应用,其中需要自定义线型。

引言

这项技术是一种生成美学线型的创新方法。 它主要适用于 CAD/GIS 和相关应用,其中需要自定义线型。 它完全使用 MFC 编写,并且非常易于使用。

背景

我当时正在研究创建自定义线型。 我生成此类线型的尝试包括

  • 使用矢量图沿给定线条布置。 这涉及使用矩阵的复杂数学计算。 但它效率低下,无法应用于填充的几何实体。
  • 使用分形几何,事实证明这也不明智,因为它需要为我感兴趣的每个线型图案发明一个新的公式。
  • 我遇到了一篇文章 使用 LineDDA 生成复杂线型 (codeguru),其中涉及使用回调过程来绘制复杂线型。 这种技术是 Win32 解决方案,目前 MFC 不直接支持。 虽然这是一个很棒的解决方案,但它并非万无一失,而且我得到的结果并不理想。 例如,当选择字符“X”作为线型图案的输入时,输出如下: (图 1&2)。
图 1. 期望的输出
图 2. 错误的输出

这促使我致力于在 MFC 中寻找更简单、更优雅且不会给普通程序员增加负担的解决方案。 我使用 Truetype (.ttf) 字体来生成线型。 字体中的每个字形 (Microsoft typography) 都可以用作线条的图案。

技巧

图 3:Windows 中的字符映射

使用 Microsoft 的字符映射应用程序(开始 > 所有程序 > 附件 > 系统工具 > 字符映射),然后从所需的字体中选择一个字符或符号(代表您的线型图案)。 每个符号都有一个与其关联的唯一十六进制数。 我们在逻辑中使用这个十六进制数。 上图中突出显示的符号的十六进制数为 0x5C。

图 3

注意:-我计划通过使用该文章 XCharMap 中的代码来扩展此应用程序 - 用于显示字符映射的对话框,作者是Hans Dietrich 在这个网站上

您可以使用 CorelDraw、Font Creator 或 Fontlab 等字体创建工具将您自己的图案设计为 Truetype 字体的符号。 将您创建的字体复制到 Windows 目录的 Fonts 文件夹中。

理解代码

我采用了 Jeff Prosise 的《使用 MFC 编程 Windows》第 3 章中的代码,用于绘制 Rubberband 线,这里不再赘述。 核心逻辑在视图类的 OnLButtonUp 中。

要沿绘制的线条排列所需的图案,首先,计算该线条的斜率和该线条相对于水平线的角度。

//calculate the slope of this line

if(point.x-m_ptFrom.x==0)
return;

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 变量,直到字符串的宽度小于线的长度。 绘制文本,我们就可以得到我们惊人的线型图案。

//Calculate Length of line segement 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 中编译并构建它。 单击并拖动以绘制 Rubberband 线。

请注意,如果从源点到目标点的绘图在线条下方绘制文本,而从目标点到源点的绘图则在线条上方绘制文本。 我们只需反转绘图顺序就可以获得反转的符号。

图 6

图 4:生成的线型图案

进一步改进

  • 从该应用程序内调用的字符映射对话框中选择所需的符号。 (让我与Hans Dietrich 联系一下)。
  • 扩展绘图逻辑,使用户能够绘制多段线和多边形。
  • 提供一个对话框,用于选择字体大小、颜色、对齐方式等。

参考文献

致谢

Pravin Ramdas Raijade

© . All rights reserved.