Scientific programming with C++Builder/Kylix

( draft . . .)

Up ABC Tutorials

C++Builder/Kylix Tutorials/Links

C++Builder/Kylix Numerical methods and scientific programming

CppMatLib

Cubic Polynomial project

(Event-driven programming)

This program displays the plot for a cubic polynomial: C0 + C1 x + C2 x2 + C3 x3.

Subjects covered:

Initial design

Start C++Builder. An empty form is created by default. Select File Save Project As, and in C++Builder Project directory create the directory SciProg as well as the subdirectory CubicPolinomial. Save Unit1 as fPolynomial and Project1 as Polynomial.

C++Builder generates the following C++ files: Polynomial.cpp, fPolynomial.h and fPolynomial.cpp. C++Builder also generates several files with IDE settings and resources (see "C++Builder generated files" in C++Builder Help).

Program file (Polynomial.cpp)

#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("fPolynomial.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
        try
        {
                 Application->Initialize();
                 Application->CreateForm(__classid(TForm1), &Form1);
                 Application->Run();
        }
        catch (Exception &exception)
        {
                 Application->ShowException(&exception);
        }
        catch (...)
        {
                 try
                 {
                         throw Exception("");
                 }
                 catch (Exception &exception)
                 {
                         Application->ShowException(&exception);
                 }
        }
        return 0;
}

Normally you do not work with the program file directly. It is automatically updated by C++Builder. 

Form header file (fPolynomial.h)

//---------------------------------------------------------------------------
#ifndef fPolynomialH
#define fPolynomialH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:// IDE-managed Components

private:// User declarations

public:// User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

In this header only one class, TForm1, is defined. It is derived from TForm declared in the Forms.hpp and introduces no new functionality. C++Builder inserts the necessary #include directives during the visual desine. You may need include your C++ files manually.  

Form source file (fPolynomial.cpp)

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "fPolynomial.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

The source file implements the constructor, which currently only calls the base class constructor. It also refers to the resources necessary for the form creation ( see the C++Builder Help for details). 

The variable Form1 of the type TForm1*  is also declared. It could be renamed in the Object Inspector. 

This is a fully-functional program (although it does nothing useful) and you can run it (click or press F9).

Note: right-clicking on fPolynomial tab and selecting Open Source/Header file toggles *.h *.cpp .

Further design

Stop the program, click on the fPolynomial tab:

and press F12 to toggle code design.

Drop Panel on the form and make it large enough for the following components. In the Object Inspector set its Name to PanelBottom, Caption empty string. Drop 8 Labels on the Panel, accept their default names and set the captions to 'X min', 'X max', 'C min', 'C max', 'C 0', 'C 1', 'C 2', 'C 3'. 

Drop 4 ScrollBars and name them 'ScrollBarC0', 'ScrollBarC1', 'ScrollBarC2', 'ScrollBarC3'. Drop 4 Edits and name them 'EditXmin', 'EditXmax', 'EditCmin', 'EditCmax'. Arrange all components according to the picture.  

Change the Anchors properties of the scrollbars to [akLeft,akRight]. This make the scrollbars to resize automatically with resizing the form. Tip: by Shift-clicking select them all and change the properties at once. Set Align property to alBottom. 

Drop another Panel on the form, assign Name to PanelTop. Set Align property to alClient. 

Drop the PaintBox component on PanelTop and set its  Align property to alClient. 

Take a look at the class TForm1 now. Note, that C++Builder updates the TForm1 class declaration.

Try to run the program.

Add some functionality

 Add the following declarations to the private section of TForm1:

private:// User declarations
        double c0, c1, c2, c3, Cmin, Cmax;
        double Xmin, Xmax, Ymin, Ymax;

        double p3(double x);
        void SetParameters();

Add the following code into fPolynomial.cpp:

// Cubic polynomial
double TForm1::p3(double x)
{
  return c0+x*(c1+x*(c2+x*c3));
}

// Reads parameters from Edits and Scrollbars,
// Calculates Y-limits
void TForm1::SetParameters()
{
  int n = 50;
  double x;

  Xmin = StrToFloat(EditXmin->Text);
  Xmax = StrToFloat(EditXmax->Text);
  Cmin = StrToFloat(EditCmin->Text);
  Cmax = StrToFloat(EditCmax->Text);
  c0 = Cmin + (Cmax-Cmin)*ScrollBarC0->Position/ScrollBarC0->Max; // Min = 0
  c1 = Cmin + (Cmax-Cmin)*ScrollBarC1->Position/ScrollBarC1->Max; // Min = 0
  c2 = Cmin + (Cmax-Cmin)*ScrollBarC2->Position/ScrollBarC2->Max; // Min = 0
  c3 = Cmin + (Cmax-Cmin)*ScrollBarC3->Position/ScrollBarC3->Max; // Min = 0
  Ymin = 1.0e+9;
  Ymax =-1.0e+9;
  for (int i = 0; i <= n; i++)
  {
    x = Xmin+(Xmax-Xmin)*i/n;
    Ymin = min(Ymin, p3(x));
    Ymax = max(Ymax, p3(x));
  }
  Ymax = Ymax + 0.1;
  Ymin = Ymin - 0.1;
}

Select Form1 from the drop-down box in the Object Inspector and flip to the Events tab. Select OnCreate and double-click on the white field to the right. It creates the procedure FormCreate in the implementation section. Add the call to SetParameters:

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  SetParameters();
}

Select PaintBox1 and select its OnPaint event. Create PaintBox1Paintprocedure by double clicking to the white field. Type the following code:

void __fastcall TForm1::PaintBox1Paint(TObject *Sender)
{
  int n = 50;
  int mX, mY, ix, iy, OldWidth;
  double x, y;

  SetParameters();
  mX = PaintBox1->ClientWidth;
  mY = PaintBox1->ClientHeight;
  PaintBox1->Canvas->Brush->Color = clWhite; // makes white backgrownd
  PaintBox1->Canvas->FillRect(PaintBox1->ClientRect); // fill PaintBox with Brush->Color
  // zero line
  ix = 0;
  y = 0.0;
  iy = int(mY*(Ymax-y)/(Ymax-Ymin)+0.5);
  PaintBox1->Canvas->MoveTo(ix, iy);
  PaintBox1->Canvas->Pen->Color = clRed;
  PaintBox1->Canvas->LineTo(mX, iy);
  PaintBox1->Canvas->Pen->Color = clBlack;
  // polynomial plot
  ix = 0;
  y = p3(Xmin);
  iy = int(mY*(Ymax-y)/(Ymax-Ymin)+0.5);
  PaintBox1->Canvas->MoveTo(ix, iy);
  OldWidth = PaintBox1->Canvas->Pen->Width;
  PaintBox1->Canvas->Pen->Width = 2;
  for (int i = 1; i <= n; i++)
  {
    x = Xmin+(Xmax-Xmin)*i/n;
    y = p3(x);
    ix = int(i*mX/n+0.5);
    iy = int(mY*(Ymax-y)/(Ymax-Ymin)+0.5);
    PaintBox1->Canvas->LineTo(ix, iy);
  };
  PaintBox1->Canvas->Pen->Width = OldWidth;
}

 The last event handler processes the scrollbars' movement. Select e.g. ScrollBarC0 and its OnChange event. Create the ScrollBarC0Change procedure:

void __fastcall TForm1::ScrollBarC0Change(TObject *Sender)
{
  PaintBox1Paint(Sender);
}

Select the same procedure for the rest of the scrollbars:

 Run the program:

The project code for C++Builder can be downloaded  here.

Kylix-specific notes

(in preparation)

Enhancement 

Other projects

 

Up Scientific programming
 

Home | Resumé |  Shokhirev.com |  Computing |  Links |  Publications

©Nikolai V. Shokhirev, 2004-2005