12,507,862 members (53,816 online)
alternative version

31.2K views
26 bookmarked
Posted

# Generating Aesthetic Line Styles

, 6 Apr 2008 CPOL
 Rate this:
A novel way to create complex line patterns

## Introduction

This technique is an innovative way of generating aesthetic line types. It is useful mainly in CAD/GIS and allied applications where there is a need for customized line types. It is written entirely using MFC and is very simple to use.

## Background

I was researching on creating custom line types. My efforts of generating such line types included:

• Use of Vector drawings to lay down along a given line. It involved complex math using matrices. But it was inefficient and could not be applied for geometrical entities that are filled.
• Use of fractal geometry, which too proved unwise as it required an effort to invent a new formula for every line pattern that I am interested in.
• I came across an article using LineDDA to produce complex line styles which involved the use of Callback procedures to draw complex line types. This technique is a Win32 solution and is currently not supported directly by MFC. Although it is a brilliant solution, it was not fool proof and I was getting undesired output. For instance, when I have chosen character “X” as input for line pattern, the outputs are as follows: (Fig 1&2).
 Fig 1. Desired Output Fig 2. Wrong Output

This motivated me to work for the solution in MFC that is simpler, elegant and not taxing on the intellect of an average programmer. I have used Truetype (.ttf) fonts to generate line types. Each Glyph in the font can be used as a pattern for the line.

## The Technique

Fig 3: Character Maps in Windows

Use Microsoft's Character Map Application (Start >All Programs > Accessories > System Tools > Character Map) and select a character or symbol (which represents a pattern for your line type) from a desired font. Each symbol has a unique hexadecimal number associated with it. We make use of this hexadecimal number in our logic. The symbol highlighted in the above image has a hexadecimal number 0x5C. See Fig 3.

Note: I am planning to extend this application by making use of code in the article, XCharMap - A dialog to display a character map by Hans Dietrich on this site.

You may design your own patterns as symbols of a Truetype font using Font creation tools like CorelDraw, Font Creator or Fontlab. Copy the Font you have created into Fonts folder of Windows Directory. This can be done by going to Control Panel and Fonts folder in it.

## Understanding the Code

I have adopted the code for drawing the Rubberband line from Chapter 3 of Jeff Prosise's 'Programming Windows with MFC', which I am not explaining here.The core logic is in `OnLButtonUp `of view class.

To arrange a desired pattern along the line drawn, first, compute the slope of the line and angle subtended by the line w.r.t. horizontal.

```//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;```

Assign the angle to the Orientation and Escapement properties of `LOGFONT `variable. Select the Font of interest and assign the Hexadecimal value of the character/symbol to a `CString `variable.

```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```

Find length of the line segment and repeatedly add the hexadecimal value of the character/symbol to the `CString `variable until the width of `string `is less than length of line. Draw the text and we get our amazing line patterns.

```//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;
}```

## Running the Application

Compile the source and build it in VS6 (or) use the executable in AestheticLines_Demo.zip. Click and drag to draw a Rubberband line. Observe that, We get the inverted symbol by just reversing the order of drawing. See Fig 4 below:

Fig 4: Line Patterns Generated

## Further Improvement

• Selection of desired symbol from a Character Map Dialog box invoked from within this application. (Let me contact Hans Dietrich on that.)
• Extend the drawing logic for enabling user to draw polylines and polygons.
• Provide a Dialog box for selecting Font size, color, alignment, etc.

## History

• 6th April, 2008: Initial post

## Share

 Software Developer India
He works in the GIS and allied technologies. His areas of Interest are GIS/CAD ,Defence,Aerospace and Law Enforcement.

## You may also be interested in...

 Pro Pro

 First Prev Next
 can not unzip the zipped source files Kevin_0775-Nov-13 15:02 Kevin_077 5-Nov-13 15:02
 Thank you a lot of mwwt27-Apr-08 16:00 mwwt 27-Apr-08 16:00
 Great Idea! TF_Productions8-Apr-08 4:07 TF_Productions 8-Apr-08 4:07
 Re: Great Idea! Durga Prasad Dhulipudi11-Apr-08 0:04 Durga Prasad Dhulipudi 11-Apr-08 0:04
 Last Visit: 31-Dec-99 18:00     Last Update: 28-Sep-16 14:17 Refresh 1