**Developing the application of program of drawing the graph of the two variables function z=f(x,y)**

In this theme is described the application developing of drawing the graph of two variables function

*z* = *f*(*x*, *y*)

As an example, the following function is realized:

*z* = sin(*x*) + cos(*y*)

Using the given example, you can create own programs to drawing the graphs of other functions.

### Contents

**Task****The mathematical formulation of the problem****Instuctions**- 1. Run Delphi. Create the project as VCL Forms Application
- 2. Develop the form Form1
- 3. Creating the form Form2
- 4. Entering the internal variables in the Form2 form
- 5. Programming the internal methods of the form Form2
- 6. Programming of event handlers of click on the buttons of rotation of graph in form Form2
- 7. Programming of event handler of activation of form Form2
- 8. Programming the event handlers of rotation of graph using mouse
- 9. The event programming of clicking on the button “Show graph …” from the form Form1
- 10. Run the application

**Task**

Is given the formula of function of two variables *z* = sin(*x*) + cos(*y*). Develop the application, which draws the graph of this function in a separate form.

In additional, you need realize the rotation of graph. Also program must be display the axes *OX*, *OY, OZ.*

**The mathematical formulation of the problem**

Building a function of two variables is a mathematical solved problem, which uses known calculation formulas.

The graph of the two variables *z*(*x*, *y*) is constructed in a parallelepiped with dimensions (xx1, xx2), (yy1, yy2), (zz1, zz2).

To use the system of rotation in 3-dimensional space, there is the concept of the point (x0, y0, z0), relative to which the rotation of the coordinate system is realized.

Also, there is the concept of angles:

The shift in the point (x0, y0, z0) based on the rotation angles and is described by the known relations

After matrix multiplication we obtain the formula for the calculation:

According to this formula will be the transformation of the coordinate system and scaling (Figure 1).

Figure 1. The shift and rotation of the coordinate system

You must decide in what the monitor plane will be located the axes *OX*, *OY*, *OZ.* We accept that in the plane of the monitor are the axis *OX* and *OY.* A *OZ* axis is perpendicular to the screen.

The coordinates of calculation point (x, y) are pressed to the point (0, 0) by the formulas:

where *A*, *a* – the coefficients of perspective that are chosen experimentally depending on the function.

**Instructions**

##### 1. Run Delphi. Create the project as VCL Forms Application

Detailed example of creating a new project in Delphi 2010 is described **here**.

Create the project as VCL Form Application. Save the project. Automatically, the main form of application is created. The name of source module of main form is “Unit1.cs”. The name of main form is “Form1”.

##### 2. Develop the form Form1

Create a form as shown in Figure 2.

Figure 2. The view of main form of program

On the form is placed the component of type “TButton”, which is intended to call an event handler of drawing the function graph. As a result, the object named “Button1” will be got.

In the component Button1 using Object Inspector you need to set the property Caption to value “Show the graph …”.

##### 3. Creating the form Form2

Create a new form as shown in Figure 3. The detailed process of a new form creating is described here. Automatically form named “Form2” will be created. The name of file of Form2 is “Unit2.pas”.

This form will be display a graph of function.

Figure 3. The form Form2 in design mode

From the “Tool Palette“, place on the form components of the following types:

- from tab “Standard” four components of type TButton, which represent the arrows of direction of rotation the function graph. As a result, the four objects-variables with names Button1, Button2, Button3, Button4 will be got;
- from tab “Additional” a component of type TImage, where the graph of function will be displayed. The object with name Image1 will be created.

Use the Object Inspector to carry out the setting of the following components:

- in the component Button1 property Caption = “^”;
- in component Button2 property Caption = “v”;
- in component Button3 property Caption = “<”;
- in component Button4 property Caption = “>”.

##### 4. Entering the internal variables in the Form2 form

All internal variables, that are used to draw the graph, are placed on the form Form2. Therefore, first, you need to activate module “Unit2.pas”.

In the module of form “Form2” are inputted the following variables with the class of visibility “private”:

- xx1, xx2, yy1, yy2 – correspond to coordinates of points, which are displayed on the screen;
- arrays xx and yy are intended to display a plane of the 4 pixels. The domain of the function
*z*=*f*(*x*,*y*) is divided into rectangles, in any of which the function is extrapolated by the edges of quadrangle.

In the “public” section are inputted:

- variables X_min, Y_min, X_max, Y_max of real type, which are the real coordinates of parallelepiped, in which the graph of function is shown. These variables are filled from the main form Form1 experimentally;
- variables “alfa”, “beta” of real type, which display the angles for the graph of the function. They are filled from the main form Form1;
- variables x0, y0, z0 of real type. They display the values from main formula of calculation (see the mathematical formulation of the problem);
- variable A of the real type. It represents the coefficient of perspective and it is chosen experimentally;
- variable f_show of a logical type is used to indicate that the need to redraw the graph, in the case of changes in the position angles alfa and beta.

After inputting the variables into the text of program, the code snippet of Form2 is following:

**type**
TForm2 = **class**(TForm)
...
** private**
{ Private declarations }
xx1, xx2, yy1, yy2 : integer;
xx, yy : array[0..3] of integer;
** public**
{ Public declarations }
// Data, which are filled to Form1
X_min, Y_min, X_max, Y_max: real;
alfa, beta:real;
x0, y0, z0:real;
A:real;
f_show:boolean;
...
** end**;

Variables, which have the access identifier “public”, are filled from the form Form1.

##### 5. Programming the internal methods of the form Form2

Into the class Form2 are inputted three additional methods:

- function Zoom_XY() of converting of coordinates system and scaling;
- function func() for which the graph is showed;
- function Show_Graphic() of drawing the graph.

After inputting of internal methods, the code snippet of class Form2 is following:

**type**
TForm2 = **class**(TForm)
...
** private**
{ Private declarations }
xx1, xx2, yy1, yy2 : integer;
xx, yy : array[0..3] of integer;
// internal methods
** procedure** Zoom_XY(x,y,z:**real**; var xx,yy:**integer**);
** procedure** Show_Graphic;
** function** func(x,y:real):real;
** public**
{ Public declarations }
// Data, which are filled to Form1
X_min, Y_min, X_max, Y_max: real;
alfa, beta:real;
x0, y0, z0:real;
A:real;
f_show:boolean;
** end**;
...

Listing of procedure of converting of system coordinates is following:

**procedure** TForm2.Zoom_XY(x: Real; y: Real; z: Real; var xx: Integer; var yy: Integer);
**var**
tx, ty, tz:real;
xn, yn, zn:real;
**begin**
tx := (x-x0)*cos(alfa) - (y-y0)*sin(alfa);
ty := ((x-x0)*sin(alfa) + (y-y0)*cos(alfa)) * cos(beta) - (z-z0)*sin(beta);
tz := ((x-x0)*sin(alfa) + (y-y0)*cos(alfa)) * sin(beta) + (z-z0)*cos(beta);
xn := tx/(tz/A+1);
yn := ty/(tz/A+1);
xx := Trunc(Image1.Width * (xn-X_min)/(X_max-X_min));
yy := Trunc(Image1.Height * (yn-Y_max)/(Y_min-Y_max));
**end**;

Drawing the graph of function is realized in procedure Show_Graphic. Listing of procedure Show_Graphic is following.

**procedure** TForm2.Show_Graphic;
**const**
h = 0.1;
h0 = 0;
**var**
i,j:integer;
canv:TCanvas;
**begin**
canv := Image1.Canvas;
// clear the canvas
canv.Rectangle(-1,-1, Image1.Width, Image1.Height);
// drawing axes
Zoom_XY(0,0,0,xx1,yy1);
Zoom_XY(1.2,0,0,xx2,yy2);
canv.MoveTo(xx1,yy1);
canv.LineTo(xx2,yy2);
canv.TextOut(xx2+3,yy2,'X');
Zoom_XY(0,0,0,xx1,yy1);
Zoom_XY(0,1.2,0,xx2,yy2);
canv.MoveTo(xx1,yy1);
canv.LineTo(xx2,yy2);
canv.TextOut(xx2+3,yy2,'Y');
Zoom_XY(0,0,0,xx1,yy1);
Zoom_XY(0,0,1.2,xx2,yy2);
canv.MoveTo(xx1,yy1);
canv.LineTo(xx2,yy2);
canv.TextOut(xx2+3,yy2-3,'Z');
// drawing the surface
** for** j:=0 **to** 9 **do**
** for** i:=0 to 9 **do**
** begin**
Zoom_XY(h0+h*i, h0+h*j, func(h0+h*i, h0+h*j), xx[0], yy[0]);
Zoom_XY(h0+h*i, h+h*j, func(h0+h*i, h+h*j), xx[1], yy[1]);
Zoom_XY(h+h*i, h+h*j, func(h+h*i, h+h*j), xx[2], yy[2]);
Zoom_XY(h+h*i, h0+h*j, func(h+h*i, h0+h*j), xx[3], yy[3]);
canv.Polygon([Point(xx[0], yy[0]), Point(xx[1], yy[1]),
Point(xx[2], yy[2]), Point(xx[3], yy[3])]);
** end**;
**end**;

Let’s explain some code snippets in procedure Show_Graphic().

The domain of the function *z* = *f* (*x*, *y*) is divided into rectangles, in any of which the function is extrapolated by the edges of the quadrangle. Construction of quadrangles on the screen is implemented by a method Polygon().

After clearing of canvas, occurs the drawing of axes, also fragments of the surface are displayed by Polygon() method.

When the surface is drawn, from the method Show_Graphic () is called Zoom_XY() method that performs conversion and scaling of the actual coordinates to screen coordinates.

Listing of method func() is following.

**function** TForm2.func(x: Real; y: Real):real;
**begin**
func := sin(x) + cos(y);
**end**;

In this method, instead a string

`func := sin(x) + cos(y);`

you can insert your own function.

##### 6. Programming of event handlers of click on the buttons of rotation of graph in form Form2

The rotation of graph occurs at the moment, when user clicks on one of the buttons, placed on the form Form2 (components Button1, Button2, Button3, Button4).

Display graphics depends on the internal variables alpha and beta. Variable “alfa” contains the rotation angle relative to the axis *OZ.* Variable “beta” contains the rotation angle relative to the axis *OX.* Therefore, in the event handlers the values “alfa” and “beta” are changed to some value. Optionally, you can set your own value of changing of alpha and beta.

Listing of event handlers is following.

**procedure** TForm2.Button1Click(Sender: TObject);
**begin**
beta := beta + 0.1;
Show_Graphic;
**end**;
**procedure** TForm2.Button2Click(Sender: TObject);
**begin**
beta := beta - 0.1;
Show_Graphic;
**end**;
**procedure** TForm2.Button3Click(Sender: TObject);
**begin**
alfa := alfa + 0.1;
Show_Graphic;
**end**;
**procedure** TForm2.Button4Click(Sender: TObject);
**begin**
alfa := alfa - 0.1;
Show_Graphic;
**end**;

##### 7. Programming of event handler of activation of form Form2

At the moment of calling of form Form2 the graph of function can be drawn. Therefore in the event handler OnActivate of Form2 is called method Show_Graphic.

**procedure** TForm2.FormActivate(Sender: TObject);
**begin**
Show_Graphic;
**end**;

##### 8. Programming the event handlers of rotation of graph using mouse

To realize the rotation of graph using mouse, you need to program the following event handlers of Image1 component.

If you are press the mouse button and then hold down it over the “Form2” form and let go it, then such events are generated (Figure 4):

- MouseDown – is generated, when user clicks on the component Image1;
- MouseMove – is generated, when user moves the mouse over the component Image1;
- MouseUp – is generated if the user releases the mouse button after clicking.

Figure 4. Events OnMouseDown, OnMouseMove, OnMouseUp of Image1 component

Moving the mouse, while holding down the button on the Image1 component, causes a change in the angles alfa and beta. Variable f_show is used to indicating to the event handler OnMouseMove that variables alfa and beta are changed and you need redraw the graph.

Listing of event handlers OnMouseDown, OnMouseMove and OnMouseUp are follows.

**procedure** TForm2.Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
**begin**
f_show := **true**;
**end**;
**procedure** TForm2.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
**var**
a, b:real;
**begin**
** if** f_show **then**
** begin**
a := x - Width div 2;
b := y - Height div 2;
if a<>0 then
alfa := arctan(b/a)
else
alfa := Pi/2;
beta := sqrt(sqr(a/10) + sqr(b/10));
Show_Graphic;
** end**;
**end**;
**procedure** TForm2.Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
**begin**
f_show := false;
**end**;

##### 9. The event programming of clicking on the button “Show graph …” from the form Form1

When you click on the button1 from form “Form1” the graph of function can be displayed.

The event handler of clicking on the button Button1 is following:

**procedure** TForm1.Button1Click(Sender: TObject);
**begin**
Form2.f_show := **false**;
Form2.x0 := 0;
Form2.y0 := 0;
Form2.z0 := 0;
Form2.A := -8;
Form2.alfa := 10;
Form2.beta := 12;
Form2.X_min := -3;
Form2.X_max := 3;
Form2.Y_min := -3;
Form2.Y_max := 3;
Form2.ShowModal;
**end**;

As you can see, before the showing of form Form2, the values of internal variables are formed. These values are chosen experimentally and may vary for each function.

##### 10. Run the application

Now you can run the application and test it (Figure 5).

Figure 5. Execution of the program