Добавил:
korayakov
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Курсовые / Курсовые ЭТМО / 03 / KURS
.CPP#include <graphics.h>
#include <stdio.h>
#include <math.h>
#include <conio.h>
// Maximum graphs displayed at one time
#define MAX_GRAPHS 10
// Best grid step
#define BEST_STEP 60
// Number format
#define NUM_FORMAT "%.1f"
// Axis labels
const char * szXLabel = "w";
const char * szYLabel = "A(w)";
// Our parameters
float T = 0.1; // time constant
double xsi; // coefficient
// structure to define a point
typedef struct
{
float x;
float y;
} POINT, *LPPOINT;
// Function definition
typedef float (*GRAPHFUNC)(float fArg);
// Our calculation function
float CalcFunction (float fArg)
{
return (1.0/sqrt( pow(1-pow(T*fArg,2), 2) + 4*pow(xsi*T*fArg,2) ));
}
// Class CGraph - for drawing
class CGraph
{
public:
void Create (POINT &ptLT, POINT &ptRB, POINT &ptMin, POINT &ptMax);
void SetFunc (GRAPHFUNC lpFunc);
void DrawGraph (int iColor);
void DrawGrid ();
char * m_szXAxis;
char * m_szYAxis;
protected:
int LogicalXToScreenX (float x);
int LogicalYToScreenY (float y);
protected:
GRAPHFUNC m_lpFunc;
POINT m_ptLeftTop;
POINT m_ptRightBottom;
float m_iMinX;
float m_iMaxX;
float m_iMinY;
float m_iMaxY;
int m_iGridCoef[3];
float m_iPropCoef;
float m_fCorrX;
float m_fCorrY;
};
void CGraph::Create (POINT &ptLT, POINT &ptRB, POINT &ptMin, POINT &ptMax)
{
m_ptLeftTop = ptLT;
m_ptRightBottom = ptRB;
m_iMinX = ptMin.x;
m_iMinY = ptMin.y;
m_iMaxX = ptMax.x;
m_iMaxY = ptMax.y;
m_iGridCoef[0]=1;
m_iGridCoef[1]=2;
m_iGridCoef[2]=5;
// Coordinate transformation coefficients
m_fCorrX = ((float)m_ptRightBottom.x-m_ptLeftTop.x)/(m_iMaxX-m_iMinX);
m_fCorrY = ((float)m_ptRightBottom.y-m_ptLeftTop.y)/(m_iMaxY-m_iMinY);
}
void CGraph::SetFunc (GRAPHFUNC lpFunc)
{
m_lpFunc = lpFunc;
}
// Draw graph
void CGraph::DrawGraph (int iColor)
{
setlinestyle (SOLID_LINE, 0, 1);
float corrx = ((float)(m_iMaxX-m_iMinX))/(m_ptRightBottom.x-m_ptLeftTop.x);
float fArg;
int x, y;
setcolor (iColor);
moveto (m_ptLeftTop.x, LogicalYToScreenY(m_lpFunc(m_iMinX)));
for (x=m_ptLeftTop.x; x<m_ptRightBottom.x; x++) {
fArg = (x-m_ptLeftTop.x)*corrx + m_iMinX;
lineto (x, LogicalYToScreenY (m_lpFunc(fArg)) );
}
}
// Draw coordinate grid
void CGraph::DrawGrid()
{
float stepx, stepy;
float c = 1;
int k=0;
float delta, mindelta;
// Select best step on OX direction...
float cur = c*m_iGridCoef[k]*m_fCorrX;
mindelta = fabs(BEST_STEP-cur);
while (1) {
if (cur>BEST_STEP) {
if (k>0) k--;
else c/=10;
}
else if (cur<BEST_STEP) {
if (k<2) k++;
else c*=10;
}
cur = c*m_iGridCoef[k]*m_fCorrX;
delta = fabs(BEST_STEP-cur);
if (delta<mindelta)
mindelta = delta;
else if (mindelta==delta)
break;
}
stepx = c*m_iGridCoef[k];
// Select best step on OY direction...
cur = c*m_iGridCoef[k]*m_fCorrY;
mindelta = fabs(BEST_STEP-cur);
while (1) {
if (cur>BEST_STEP) {
if (k>0) k--;
else c/=10;
}
else if (cur<BEST_STEP) {
if (k<2) k++;
else c*=10;
}
cur = c*m_iGridCoef[k]*m_fCorrY;
delta = fabs(BEST_STEP-cur);
if (delta<mindelta)
mindelta = delta;
else if (mindelta==delta)
break;
}
stepy = c*m_iGridCoef[k];
// Calculate start and end logical coordinates
float iStartX, iStartY;
float iEndX, iEndY;
iStartX = ((int)(m_iMinX/stepx))*stepx;
iStartY = ((int)(m_iMinY/stepy))*stepy;
iEndX = ((int)(m_iMaxX/stepx))*stepx;
iEndY = ((int)(m_iMaxY/stepy))*stepy;
float lx, ly; // Logical coordinates (current)
int x, y;
// Draw axises (OY)
settextstyle(1,0,1);
if (m_iMinX>=0)
lx = m_iMinX;
else if (m_iMinX<0 && m_iMaxX>0)
lx = 0;
else
lx = m_iMaxX;
setcolor (1);
setlinestyle (0, 0, 3);
x = LogicalXToScreenX(lx);
moveto (x, m_ptRightBottom.y+15);
lineto (x, m_ptLeftTop.y-15);
linerel (-3, 10); linerel (6, 0); linerel(-3, -10);
outtextxy (x+10, m_ptLeftTop.y-20, m_szYAxis);
// Draw axises (OX)
if (m_iMinY>=0)
ly = m_iMinY;
else if (m_iMinY<0 && m_iMaxY>0)
ly = 0;
else
ly = m_iMaxY;
setcolor (4);
y = LogicalYToScreenY(ly);
moveto (m_ptLeftTop.x-15, y);
lineto (m_ptRightBottom.x+15, y);
linerel (-10, -3); linerel (0, 6); linerel(10, -3);
outtextxy (m_ptRightBottom.x+15-textwidth(m_szXAxis), y, m_szXAxis);
// Draw bounding rectangle
setlinestyle(0,0,1);
setcolor(7);
rectangle (m_ptLeftTop.x-20, m_ptLeftTop.y-20, m_ptRightBottom.x+20, m_ptRightBottom.y+20);
char sz[10];
// Draw grid
setlinestyle (USERBIT_LINE, 0x5555, 1);
settextstyle(2,0,2);
for (lx=iStartX; lx<=iEndX; lx+=stepx) {
x = LogicalXToScreenX(lx);
moveto (x, m_ptLeftTop.y);
lineto (x, m_ptRightBottom.y);
if (lx!=iStartX && lx!=iEndX) {
sprintf(sz, NUM_FORMAT, lx);
outtextxy (x-textwidth(sz)/2, m_ptRightBottom.y, sz);
}
}
for (ly=iStartY; ly<=iEndY; ly+=stepy) {
y = LogicalYToScreenY(ly);
moveto (m_ptLeftTop.x, y);
lineto (m_ptRightBottom.x, y);
if (ly!=iStartY && ly!=iEndY) {
sprintf(sz, NUM_FORMAT, ly);
outtextxy (m_ptLeftTop.x-textwidth(sz), y-textheight(sz)/2, sz);
}
}
}
int CGraph::LogicalXToScreenX (float x)
{
return m_ptLeftTop.x + ( x-m_iMinX )*m_fCorrX;
}
int CGraph::LogicalYToScreenY (float y)
{
return m_ptRightBottom.y - ( y-m_iMinY )*m_fCorrY;
}
// Class CLegend - draws a legend of a values
class CLegend
{
public:
void Create (POINT &ptLT, POINT &ptRB);
void Add (float fVal, int iColor);
protected:
POINT m_ptLeftTop;
POINT m_ptRightBottom;
int m_iLastX;
};
void CLegend::Create(POINT &ptLT, POINT &ptRB)
{
m_ptLeftTop = ptLT;
m_ptRightBottom = ptRB;
m_iLastX = ptLT.x+10;
setcolor (7);
rectangle (ptLT.x, ptLT.y, ptRB.x, ptRB.y);
}
void CLegend::Add (float fVal, int iColor)
{
setcolor(7);
settextstyle(2,0,2);
char sz[10];
sprintf (sz, "ksi=%.2f", fVal);
rectangle (m_iLastX, m_ptLeftTop.y+10, m_iLastX+10, m_ptLeftTop.y+20);
setfillstyle (1, iColor);
bar (m_iLastX+1, m_ptLeftTop.y+11, m_iLastX+9, m_ptLeftTop.y+19);
outtextxy (m_iLastX+15, m_ptLeftTop.y+10, sz);
m_iLastX+=64;
}
// Program entry point
void main ()
{
// Clear screen
clrscr ();
// Init graphic mode
int iDriver = DETECT, iMode, iError;
// This is a path to BGI driver
char szDriverPath[] = "D:\\BORLANDC\\BGI";
initgraph (&iDriver, &iMode, szDriverPath);
iError = graphresult();
if (iError!=grOk) {
// Error initializing graphic mode
puts ("ERROR: Initializing graphic mode");
puts ("Unexpected program termination...");
return;
}
// Define points for our graphs
POINT ptLT = {20, 20}; // Left-Top corner
POINT ptRB = {619, 420}; // Right-Bottom corner
POINT ptMin = {0, 0}; // Minimum values of arg and function
POINT ptMax = {20, 6}; // Maximum values
// Define points for our legend
POINT ptlLT = {0, 450};
POINT ptlRT = {639, 479};
// Define one instance of a graph
CGraph graph;
// Define one instance of a legend
CLegend legend;
graph.Create (ptLT, ptRB, ptMin, ptMax);
graph.SetFunc (CalcFunction);
graph.m_szXAxis = (char*)szXLabel;
graph.m_szYAxis = (char*)szYLabel;
graph.DrawGrid ();
legend.Create (ptlLT, ptlRT);
int i=1;
// Draw our graphs, changing T...
for (xsi = 0.1; xsi<=1.0; xsi+=0.1) {
graph.DrawGraph (i);
legend.Add (xsi, i++);
}
if (!getch()) getch();
// Exit graphic mode
closegraph();
}