www.phys.ubbcluj.ro

4/18/2011
3. Elements of scientific graphics
Titus Beu
University “Babes-Bolyai”
Department of Theoretical and Computational Physics
Cluj-Napoca, Romania
Titus Beu 2011
Bibliography
Graphics Devices
Graphics functions of the Borland Graphics Interface (BGI)
Plotting functions of one variable
Titus Beu 2011
1
4/18/2011
Borland International, Inc., Borland C++ 3.1 Programming Guide (Borland International, Scotts
Valley, CA, 1992).
Microsoft Corporation, Microsoft Visual C++ 1.0 Programmer's Guide (Microsoft Corporation,
1993).
Beu, T. A., Numerical Calculus in C, Third Edition
(MicroInformatica Publishing House, Cluj-Napoca, 2004).
Beu, T. A., Numerical Analysis in Turbo Pascal
(MicroInformatica Publishing House, Cluj-Napoca, 1992).
Titus Beu 2011
Graphics devices:
Discrete representation – monitors and printers
Continuous representation – plotters
Monitors
Pixel – basic graphic element
Raster image – mapping of graphics memory
8, 16, 24, 32 bits / pixel – color information, brightness, etc.
Resolution – m × n – no. of horizontal × vertical pixels
Printers
Ink jet printers – line-by-line printing (slow), small memory, excellent color
Laser Jet printers – map entire pages, large memory, portable language PS
Resolution: n dpi (dots per inch)
Plotters
Step-by-step control of pen motion
Optimal for large color representations at high resolutions
Titus Beu 2011
2
4/18/2011
Borland Graphics Interface (BGI) – graphics library for the DOS operating systems
Winbgim – Windows port of the Borland Graphics Interface
GRAPHICS.H header file library with more than 80 basic graphics functions –simple
use in DOS applications
Screen coordinates are different from user coordinates
Graphics screen – rectangular area with origin in the upper left corner
Points on the screen can be addressed by their coordinates
Horizontal screen coordinates increase to the right
Vertical screen coordinates increase from top to bottom
Titus Beu 2011
Maximum values of screen coordinates – functions getmaxx() and getmaxy()
Graphics functions move the cursor on the screen analogously to a pencil on paper
(0,0)
(getmaxx(),0)
(x,y)
(0,getmaxy())
(getmaxx(),getmaxy())
Titus Beu 2011
3
4/18/2011
void far cleardevice(void);
void far closegraph(void);
int far getmaxx(void);
int far getmaxx(void);
void far initgraph(int far *driver, int far *mode, char far *path);
void far line(int x1, int y1, int x2, int y2);
void far lineto(int x, int y);
void far moveto(int x, int y);
void far outtextxy(int x,int y,char far *textstring);
void far rectangle(int left, int top, int right, int bottom);
void far settextjustify(int horiz, int vert);
void far settextstyle(int font, int direction, int charsize);
Titus Beu 2011
Consider a real function of one real variable,
f : x min , x max  → y min , y max ,
tabulated for particular argument values:
fx i  = y i , i = 1, 2, . . . , n.
Titus Beu 2011
4
4/18/2011
One cannot use user coordinates (xi,yi) as arguments for the graphics functions
Screen coordinates are obtained by a linear transform:
x̄ = A x x + Bx ,
ȳ = A y y + By .
Scaling coefficients:
x̄ min = A x x min + Bx ,
x̄ max = A x x max + Bx ,
ȳ min = A y y min + By ,
ȳ max = A y y max + By ,
⇒
⇒
A x = x̄ max − x̄ min /x max − x min 
Bx = x̄ min − A x x max .
A y = ȳ max − ȳ min /y max − y min 
By = ȳ min − A y y min .
Asymmetry between x and y axes – y-values are not ordered
Screen coordinates of tabulated points:
x̄ i = A x x i + Bx , i = 1, 2, . . . , n
ȳ i = A y y i + By .
Titus Beu 2011
//------------------------------- Graphlib.h -------------------------------//--------------------------------------------------------------------------// Contains routines for displaying plots of functions by using the
// BGI graphics interface of the Borland C++ environment
//--------------------------------------------------------------------------#ifndef _GRAPHLIB_
#define _GRAPHLIB_
#include
#include
#include
#include
#include
<stdlib.h>
<string.h>
<winbgim.h> // <graphics.h>
"Memalloc.h"
"Utils.h"
//===========================================================================
void InitGraph(void)
//--------------------------------------------------------------------------// Initialize the graphics mode
//--------------------------------------------------------------------------{
int gdriver = DETECT, gmode;
initgraph(&gdriver,&gmode,"c:/progra~1/borlandc/bgi");
}
Titus Beu 2011
5
4/18/2011
//===========================================================================
void Plot0(float x[], float y[], int n,
float fxmin, float fxmax, float fymin, float fymax)
//--------------------------------------------------------------------------// Displays the line plot of a tabulated function of one variable within the
// viewport [fxmin, fxmax] x [fymin, fymax], specified by fractional
// coordinates in the interval [0,1].
//
// x[]
- abscissas of the tabulation points
// y[]
- ordinates of the tabulation points
// n
- number of points
// fxmin
- minimum relative abscissa of viewport (0 < fxmin < fxmax < 1)
// fxmax
- maximum relative abscissa of viewport
// fymin
- minimum relative ordinate of viewport (0 < fymin < fymax < 1)
// fymax
- maximum relative abscissa of viewport
//--------------------------------------------------------------------------{
#define Nint(x) (int)floor(x + 0.5)
float ax, bx, ay, by, xmin, xmax, ymin, ymax;
int i, ixmin, ixmax, iymin, iymax;
// viewport coordinates
ixmin = Nint(fxmin*getmaxx()); iymin = Nint((1.0-fymin)*getmaxy());
ixmax = Nint(fxmax*getmaxx()); iymax = Nint((1.0-fymax)*getmaxy());
rectangle(ixmin,iymax,ixmax,iymin);
// frame
xmin = x[1]; xmax = x[n];
ax = (ixmax-ixmin)/(xmax-xmin);
bx = ixmin - ax*xmin;
// X-Axis
// scaling coefficients
Titus Beu 2011
ymin = y[1]; ymax = y[1];
for (i=2; i<=n; i++) {
if (ymin > y[i]) ymin = y[i];
if (ymax < y[i]) ymax = y[i];
}
if (ymin == ymax) { ymin *= 0.9; ymax *= 1.1; }
ay = (iymax-iymin)/(ymax-ymin);
by = iymin - ay*ymin;
// Y-Axis
// ymin and ymax
// scaling coefficients
// draw axes
if (xmin*xmax < 0) line(Nint(bx),iymin,Nint(bx),iymax);
if (ymin*ymax < 0) line(ixmin,Nint(by),ixmax,Nint(by));
moveto(Nint(ax*x[1]+bx),Nint(ay*y[1]+by));
// first point
for (i=2; i<=n; i++) lineto(Nint(ax*x[i]+bx),Nint(ay*y[i]+by));
}
#endif
Mechanism that allows the header file to be included just once
#ifndef _GRAPHLIB_
#define _GRAPHLIB_
..........
#endif
Titus Beu 2011
6
4/18/2011
To be informative, the plot needs ticks and labels
In order to be multiples of useful equidistances, the axes need usually to be
expanded
Plots of function f(x) = x exp(-x):
Titus Beu 2011
//===========================================================================
void Plot(float x[], float y[], int n, int istyle,
float fxmin, float fxmax, float fymin, float fymax,
char xtext[], char ytext[], char title[])
//--------------------------------------------------------------------------// Displays the line plot of a tabulated function of one variable within the
// viewport [fxmin, fxmax] x [fymin, fymax], specified by fractional
// coordinates in the interval [0,1]. The x and y axis limits are extended
// to include an integer number < 10 of subintervals of length expressible as
// d * 10 ^ p, where d is 1, 2 or 5 and p is integer. The axes are labeled
// automatically.
//
// x[]
- abscissas of the tabulation points
// y[]
- ordinates of the tabulation points
// n
- number of points
// istyle - style of representation 0 - with squares
//
1 - with continuous line
// fxmin
- minimum relative abscissa of viewport (0 < fxmin < fxmax < 1)
// fxmax
- maximum relative abscissa of viewport
// fymin
- minimum relative ordinate of viewport (0 < fymin < fymax < 1)
// fymax
- maximum relative abscissa of viewport
// xtext[] - x-axis title
// ytext[] - y-axis title
// title[] - plot title
//--------------------------------------------------------------------------{
float ax, bx, ay, by, h, htic, scale, xmin, xmax, ymin, ymax;
int ix, ixmin, ixmax, ixtext, iy, iymin, iymax, iytext;
int charX, charY, i, nsigd, nintv, tic;
char mant[10], expn[5], text[50];
Titus Beu 2011
7
4/18/2011
charX = textwidth ("0");
charY = textheight("0");
// average character size
// viewport coordinates
ixmin = Nint(fxmin*getmaxx()); iymin = Nint((1.0-fymin)*getmaxy());
ixmax = Nint(fxmax*getmaxx()); iymax = Nint((1.0-fymax)*getmaxy());
rectangle(ixmin,iymax,ixmax,iymin);
// frame
xmin = x[1]; xmax = x[n];
// X-Axis
Limits(xmin,xmax,scale,nsigd,nintv);
// extended limits
ax = (ixmax-ixmin)/(xmax-xmin);
// scaling coefficients
bx = ixmin - ax*xmin;
h = (xmax-xmin)/nintv; htic = ax * h;
// labeling step
tic = (ixmax-ixmin)/75;
// tic length
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
settextjustify(CENTER_TEXT,TOP_TEXT);
iytext = iymax - 3*charY;
outtextxy((ixmin+ixmax)/2,iytext,title);
// plot title
iytext = iymin + charY;
for (i=1; i<=nintv+1; i++) {
// label axis
ix = Nint(ixmin + (i-1)*htic);
line(ix,iymin,ix,iymin-tic);
// tics
line(ix,iymax,ix,iymax+tic);
Format(xmin+(i-1)*h,scale,nsigd,mant,expn);
outtextxy(ix-charX/2,iytext,mant);
// labels
}
iytext = iytext + 2*charY;
strcpy(text,xtext);
if ((scale<1.0) || (scale>1000.0)) strcat(strcat(text,"
x 1e"),expn);
outtextxy((ixmin+ixmax)/2,iytext,text);
// axis title
Titus Beu 2011
ymin = y[1]; ymax = y[1];
// Y-Axis
for (i=2; i<=n; i++) {
// ymin and ymax
ymin = min(ymin,y[i]);
ymax = max(ymax,y[i]);
}
if (ymin == 0.0 && ymax == 0.0) { ymin = -0.1; ymax = 0.1; }
if (fabs(ymax-ymin) < 1e-5*fabs(ymax)) { ymin *= 0.9; ymax *= 1.1; }
Limits(ymin,ymax,scale,nsigd,nintv);
// extended limits
ay = (iymax-iymin)/(ymax-ymin);
// scaling coefficients
by = iymin - ay*ymin;
h = (ymax-ymin)/nintv; htic = ay * h;
// labeling step size
settextjustify(RIGHT_TEXT,CENTER_TEXT);
ixtext = ixmin - charY;
for (i=1; i<=nintv+1; i++) {
// label axis
iy = Nint(iymin + (i-1)*htic);
line(ixmin,iy,ixmin+tic,iy);
// tics
line(ixmax,iy,ixmax-tic,iy);
Format(ymin+(i-1)*h,scale,nsigd,mant,expn);
outtextxy(ixtext,iy,mant);
// labels
}
ixtext = ixtext - charY - charX * strlen(mant);
strcpy(text,ytext);
if ((scale<1.0) || (scale>1000.0)) strcat(strcat(text,"
x 1e"),expn);
settextstyle(DEFAULT_FONT,VERT_DIR,1);
outtextxy(ixtext,(iymin+iymax)/2,text);
// axis title
// draw axes
if (xmin*xmax < 0) line(Nint(bx),iymin,Nint(bx),iymax);
if (ymin*ymax < 0) line(ixmin,Nint(by),ixmax,Nint(by));
Titus Beu 2011
8
4/18/2011
ix = Nint(ax*x[1]+bx); iy = Nint(ay*y[1]+by);
// first point
tic = (ixmax-ixmin)/125;
if (istyle) moveto(ix,iy); else rectangle(ix-tic,iy-tic,ix+tic,iy+tic);
for (i=2; i<=n; i++) {
// loop over points
ix = Nint(ax*x[i]+bx); iy = Nint(ay*y[i]+by);
if (istyle) lineto(ix,iy); else rectangle(ix-tic,iy-tic,ix+tic,iy+tic);
}
}
Titus Beu 2011
9