Introduction
This article is intended to provide a simple C graphics library for the replacement of old BASIC graphic commands such as HPLOT
and HCOLOR
. This library does not provide on-screen graphics functions but has the ability to export graphical output to BMP or WMF. I hope that this library will be a help for programmers who want to make their own graphics library for simple physics simulations.
Background
I was studying physics simulations and found a wonderful book published in 1984. The author implemented all the simulation algorithms in Apple II BASIC and he used HPLOT
and HCOLOR
for graphical result. So there were some issues for further study. The old BASIC language is no longer used. C/C++ compilers such as Turbo-C can not be run without a DOSBox. I did not want to install Python or the GD library. What I wanted was a tiny and portable graphics library that could produce raster or vector graphical output for physics simulations.
Python and Python extension packages was a great solution but it did not meet my requirements. Neither did the GD library which supports just raster graphical outputs. Therefore I decided to make my own simple graphics library which would be able to export graphics results to BMP and WMF.
Using the Code
The following BASIC code implements a simple motion. This program plots the X (position) vs. T (time) in the case of a = dv/dt = -x.
10 15 20 INPUT "SCALE OF T-AXIS ="; K
30 INPUT "SCALE OF X-AXIS ="; L
40 HGR : HCOLOR=3
50 HPLOT 0, 40 TO 0, 140
60 HPLOT 0, 90 TO 279, 90
70 X0 = 1:V0 = 0:DT = 0.1
80 X = X0:V = V0
90 A = -X
100 V = V + A * (DT/2)
110 X = X + V * DT
120 T = T + DT
130 T1 = T * K:X1 = X * L
140 IF T1 > 270 THEN END
150 HPLOT T1, -X1 + 90
160 A = -X
170 V = V + A * DT
180 GOTO 110
]RUN
SCALE OF T-AXIS =5
SCALE OF X-AXIS = 40
The following C code gives the same graphics result:
#include <stdio.h>
#include "libtg.h"
int main()
{
float x,v,a, x0=1, v0=0, t= 0,dt=0.1,k=5,l=40,x1=0,t1=0;
float fwid = 0, fhgt = 3;
int xwid=279, xhgt = 180;
TG_Color pixel_color = TG_GetColor(TG_BLACK);
TG_PlotZone_Ptr zone=NULL;
TG_Workspace_Ptr workspace = TG_InitTGLibrary("Letter");
if(!workspace) return 1;
zone = &workspace->zone;
fwid = fhgt*((float)xwid/xhgt);
TG_SetFrame(&workspace->zone.frame, 0, 0, fwid, fhgt, 0, xwid, 0, xhgt);
TG_BMP_OpenExport(zone, "sm.bmp", xwid, xhgt, 1);
TG_BMP_SetReverseWorldCoord(1);
x = x0;
v = v0;
a = -x;
v + = a*dt/2;
while(1) {
x += v*dt;
t += dt;
t1 = t*k;
x1 = x*l;
if(t1 > 270) break;
a = -x;
v += a*dt;
zone->plot.putpixel1(zone, t1, -x1+90, pixel_color);
}
TG_BMP_CloseExport();
TG_CloseTGLibrary(workspace);
return 0;
}
Coordinate System
The default coordinate system of LibTG is the world coordinate system whose origin is the lower left corner. However, export functions convert the world coordinate system into logical (paper) coord system for WMF or pixel coord system for BMP. The origin of BMP and WMF is the same, the upper left corner. The difference in the coordinate system between WMF and BMP is the unit. WMF uses inch unit, internally twip, and BMP uses pixel unit. You may change the origin of the WMF coordinate system by using SetWindowsOrg
but I will not be going into that topic here.
Usually, old BASIC simulation code uses pixel coordinate system (e.g.: HPLOT T1, -X1 + 90). Therefore, XXXAPI_SetReverseWorldCoord(1)
must be called before any plot function; XXX can be BMP or WMF. The first image represents the world coordinate system and the next one shows the paper or pixel coordinate system. There are two mapping processes in LibTG: world to logical and logical to pixel. BMP export requires both, and WMF just needs world to logical. The logical coordinate system is the alias of the paper coordinate system in inch unit. It will take a lot of time to explain the WMF format in detail. You can find the format spec on the Internet or check the WMF export part of LibTG.
TG_Point world, logical, pixel;
world.x = x, world.y = y;
World2Length(&&world, &&logical);
Length2Pixel(&&logical, &&pixel);
... putpixel(..., pixel.x, pixel.y, ...);
Example2: WMF export
TG_Point world, logical, pixel;
world.x = x, world.y = y;
World2Length(&&world, &&logical);
... putpixel(..., _to_twip(pixel.x), _to_twip(pixel.y), ...);
Now, let's export the graph to WMF. It is very simple. You just need to replace BMP with WMF and delete the last three arguments of OpenExport(..., xwid, xhgt, 1)
.
...
TG_WMF_OpenExport(zone, "sm.wmf");
TG_WMF_SetReverseWorldCoord(1);
...
TG_WMF_CloseExport();
TG_CloseTGLibrary(workspace);
return 0;
You can add a symbol by inserting just three lines. The functions gsave
and grestore
protect the properties of lines or pixels from the changed graphic status after drawing the symbols. gsave
and grestore
are valid only for WMF export. If you want just BMP, you don't need to use gsave
and grestore
.
...
zone->plot.putpixel1(zone, t1, -x1+90, pixel_color);
zone->plot.gsave();
zone->plot.symbol(zone, t1, -x1+90, TG_SYM_CIRCLE,.03,
TG_GetColor(TG_RED),1 ,TG_GetColor(TG_BLACK),1,0.001);
zone->plot.grestore();
int skip=5, iskip=0;
TG_BMP_OpenExport(zone, "sms-skip.bmp", xwid, xhgt, 1);
...
zone->plot.putpixel1(zone, t1, -x1+90, pixel_color);
if((iskip%skip)) iskip++;
else {
zone->plot.gsave();
zone->plot.symbol(zone, t1, -x1+90, TG_SYM_CIRCLE,.03,
TG_GetColor(TG_RED),1 ,TG_GetColor(TG_BLACK),1,0.001);
zone->plot.grestore();
iskip = 1;
}
Here are some funny examples and I will post just the images. Check the source code to learn more about them. These images are plots of some potential functions in uniform flow. The topics are usually dealt at the beginning of fluid mechanics. The first is a dipole under uniform flow (BMP). The second is a vortex under uniform flow (BMP). The last shows the flow behaviors around a plate with an angle of attack (BMP).
I inserted BMP and WMF files into Microsoft PowerPoint:
I made a simple WMF analyzer which saves the meta commands in a WMF file as a text format. It is very useful and intuitive when I develop a WMF library from scratch. The program has three buttons: WMF, OK, and Cancel. If you click WMF, a file dialog box appears. Choose a WMF file and a text file with the same name and ".txt" extension will be created automatically, or click the OK button. Unfortunately, I lost the source code but have the executable program. I can't upload any executable program to CodeProject. If you need it, email me.
SMW.TXT
***************************************
* Windows Meta File(16bit) Analyzer *
* 2004. 2. 2. *
* written by Euisang Hwang *
***************************************
Placeable Metafile Header
-------------------------------------
Hex Dec
-------------------------------------
DWORD MagicNumber : 0x9ac6cdd7 2596720087
WORD Handle : 000000 0
short Left : 000000 0
short Top : 000000 0
short Right : 0x1711 5905
short Bottom : 0x0ee2 3810
short Inch : 0x04f6 1270
DWORD Reserved : 0000000000 0
WORD CheckSum : 0x4a14 18964
-------------------------------------
Standard Metafile Header
-------------------------------------
Hex Dex
-------------------------------------
WORD FileType : 0x0001 1
WORD HeaderSize : 0x0009 9
WORD Version : 0x0300 768
DWORD FileSize : 0x00008d07 36103
WORD NumOfObjects : 0x057c 1404
DWORD MaxRecordSize : 0x0000001e 30
WORD NumOfParams : 000000 0
--------------------------------------
Record size : 5
API Function : 0x020b
API Prototype: DWORD SetWindowOrg (HDC,int,int)
Parameter 0 : 000000 0
Parameter 1 : 000000 0
Record size : 5
API Function : 0x020c
API Prototype: DWORD SetWindowExt (HDC,int,int)
Parameter 0 : 0x0ee2 3810
Parameter 1 : 0x1711 5905
Record size : 8
API Function : 0x02fa
API Prototype: HPEN CreatePenIndirect (LOGPEN FAR *)
Parameter 0 : PS_SOLID(0)
Parameter 1 : 1
Parameter 2 : 0
Parameter 3 : 0 (RED)
Parameter 4 : 0 (GREEN)
0 (BLUE)
..............................
Record size : 3
API Function : 000000
API Prototype: (End) (End) (End)
---------------------
Total record size : 36085
Points of Interest
I could not find any library for creating WMF files. It was very fun for me to write pure C code for making a WMF export from scratch.
How to Compile
Open a development command line by clicking the \Start\Programs\Microsoft Visual Studio\Visual Studio Tools\2005 Visual Studio 2005 Command Prompt shortcut. Type a few words: cl xxx.c libtg.c. That's it!
Setting environment for using Microsoft Visual Studio 2005 x86 tools.
C:\Program Files (x86)\Microsoft Visual Studio 8\VC>d:
D:\>cd programming\libtg
D:\programming\libtg>cl s1.c libtg.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
s1.c
libtg.c
Generating Code...
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation. All rights reserved.
/out:s1.exe
s1.obj
libtg.obj
D:\programming\libtg>s1
D:\programming\libtg>dir sms-skip.bmp ----> or sms-skip.wmf
Volume in drive D is DATA
Volume Serial Number is 7CF4-A7A1
Directory of D:\programming\libtg
07/13/2011 07:48 PM 151,254 sms-skip.bmp
1 File(s) 151,254 bytes
0 Dir(s) 142,672,297,984 bytes free
D:\programming\libtg>
Or you can make a project in Visual Studio 2005/2010 or open Watcom C/C++. Ignore the many type conversion warnings due to the double to float conversions.
Bugs and Further Development
- I have not implemented a thick line algorithm for BMP export.
- Exception handling needs to be added for safe usage.
- Disk memory option for BMP export does not work.
- Text functions need to be added.
- Lots of bugs still exist.
Conclusion
Old physics simulation books used the BASIC language. For graphical output, programmers must select other ways. Installing Open Source software or Open Source libraries may be a good solution. However, fantastic graphic functions are not needed for simple physics simulations. Just a C/C++ compiler and simple functions are enough. LibTG will be a good alternative for satisfactory quality of raster graphics or vector graphics output.
History
First of all, forgive my English. English is not my mother tongue. However, I think that C/C++ or other programming languages are universal. This article is my first try at CodeProject. I hope that all the readers will enjoy my library.