288 lines
6.5 KiB
C++
288 lines
6.5 KiB
C++
#include "stdafx.h"
|
|
#include "xyplot.h"
|
|
|
|
/*
|
|
class CXYPlot
|
|
{
|
|
public:
|
|
// data members
|
|
double **M;
|
|
double **lbls;
|
|
int NumRows;
|
|
int NumCols;
|
|
|
|
// member functions
|
|
CXYPlot();
|
|
~CXYPlot();
|
|
BOOL Create(int rows, int cols);
|
|
BOOL MakePlot();
|
|
BOOL ToDisk();
|
|
|
|
private:
|
|
}
|
|
*/
|
|
|
|
CXYPlot::CXYPlot()
|
|
{
|
|
NumRows=0;
|
|
NumCols=0;
|
|
M=NULL;
|
|
lbls=NULL;
|
|
}
|
|
|
|
CXYPlot::~CXYPlot()
|
|
{
|
|
if (NumRows==0) return;
|
|
|
|
int i;
|
|
for(i=0;i<NumRows;i++) free(M[i]);
|
|
for(i=0;i<NumCols;i++) free(lbls[i]);
|
|
free(M);
|
|
free(lbls);
|
|
NumRows=0;
|
|
NumCols=0;
|
|
}
|
|
|
|
BOOL CXYPlot::Create(int rows, int cols)
|
|
{
|
|
int i;
|
|
BOOL flag=TRUE;
|
|
|
|
NumRows=rows;
|
|
NumCols=cols;
|
|
M=(double **)calloc(rows,sizeof(double*));
|
|
lbls=(char **)calloc(cols,sizeof(char*));
|
|
if ((M==NULL) || (lbls==NULL)) flag=FALSE;
|
|
for(i=0;i<rows;i++){
|
|
M[i]=(double *)calloc(cols,sizeof(double));
|
|
if (M[i]==NULL) flag=FALSE;
|
|
}
|
|
for(i=0;i<cols;i++){
|
|
lbls[i]=(char *)calloc(80,sizeof(char));
|
|
if (lbls[i]==0) flag=FALSE;
|
|
}
|
|
|
|
if(flag==FALSE){
|
|
NumRows=0;
|
|
NumCols=0;
|
|
for(i=0;i<rows;i++) free(M[i]);
|
|
for(i=0;i<cols;i++) free(lbls[i]);
|
|
free(M);
|
|
free(lbls);
|
|
}
|
|
|
|
return flag;
|
|
}
|
|
|
|
void CXYPlot::MakePlot(CDC *pDC, char *BoundingBox)
|
|
{
|
|
double bb[4];
|
|
double HiX,LoX,HiY,LoY,dx,dy,d;
|
|
static const double Height=250.;
|
|
static const double Width=400.;
|
|
static const double OffsetX=80.;
|
|
static const double OffsetY=30.;
|
|
char s[80];
|
|
int i,j,k;
|
|
CPen PlotPen;
|
|
CPen *pOldPen;
|
|
static COLORREF PenCols[]={0x00000000,0x00ff0000,0x0000ff00,0x000000ff,
|
|
0x00ffff00,0x00ff00ff,0x0000ffff};
|
|
|
|
if (NumRows==0) return;
|
|
|
|
LoY=M[0][1];
|
|
HiY=M[0][1];
|
|
|
|
for(i=1;i<NumRows;i++)
|
|
for(j=1;j<NumCols;j++)
|
|
{
|
|
if (M[i][j]>HiY) HiY=M[i][j];
|
|
if (M[i][j]<LoY) LoY=M[i][j];
|
|
}
|
|
|
|
if(HiY==LoY){
|
|
HiY=1.;
|
|
LoY=-1.;
|
|
}
|
|
|
|
dy=pow(10.,floor(log10(HiY-LoY)));
|
|
LoY=dy*floor(LoY/dy);
|
|
HiY=dy*ceil(HiY/dy);
|
|
HiX=M[NumRows-1][0];
|
|
LoX=0.; //LoX=M[0][0];
|
|
dx=pow(10.,floor(log10(HiX-LoX)));
|
|
|
|
// scale those suckers...
|
|
for(i=0;i<NumRows;i++){
|
|
for(j=1;j<NumCols;j++)
|
|
M[i][j]=Height-(M[i][j]-LoY)*Height/(HiY-LoY)+OffsetY;
|
|
M[i][0]=(M[i][0]-LoX)*Width/(HiX-LoX)+OffsetX;
|
|
}
|
|
|
|
// compute bounding box
|
|
if (BoundingBox!=NULL)
|
|
{
|
|
bb[0]=(-(HiX*OffsetX) + LoX*(OffsetX + Width))/Width + ((HiX - LoX)*0.)/Width;
|
|
bb[1]=HiY + ((HiY - LoY)*OffsetY)/Height + ((-HiY + LoY)*343.)/Height;
|
|
bb[2]=(-(HiX*OffsetX) + LoX*(OffsetX + Width))/Width + ((HiX - LoX)*588.)/Width;
|
|
bb[3]=HiY + ((HiY - LoY)*OffsetY)/Height + ((-HiY + LoY)*0.)/Height;
|
|
sprintf(BoundingBox,"%.17g %.17g %.17g %.17g",bb[0],bb[1],bb[2],bb[3]);
|
|
}
|
|
|
|
|
|
PlotPen.CreatePen(PS_SOLID,1,PenCols[0]);
|
|
pOldPen=pDC->SelectObject( &PlotPen );
|
|
pDC->MoveTo(0,0);
|
|
pDC->LineTo(588,0);
|
|
pDC->LineTo(588,343);
|
|
pDC->LineTo(0,343);
|
|
pDC->LineTo(0,0);
|
|
|
|
pDC->MoveTo((int) OffsetX,(int) OffsetY);
|
|
pDC->LineTo((int) OffsetX,(int) (OffsetY+Height));
|
|
pDC->LineTo((int) (OffsetX+Width),(int) (OffsetY+Height));
|
|
pDC->SelectObject(pOldPen);
|
|
PlotPen.DeleteObject();
|
|
|
|
CFont fntArial,*pOldFont;
|
|
fntArial.CreateFont(12,0,0,0,0,0,0,0,0,0,0,0,0,"Tahoma");
|
|
pOldFont=pDC->SelectObject(&fntArial);
|
|
|
|
// draw those suckers...
|
|
for(i=1;i<NumCols;i++){
|
|
PlotPen.CreatePen(PS_SOLID,1,PenCols[i-1]);
|
|
pOldPen=pDC->SelectObject( &PlotPen );
|
|
pDC->MoveTo((int)M[0][0],(int)M[0][i]);
|
|
for(j=0;j<NumRows;j++)
|
|
pDC->LineTo((int)M[j][0],(int)M[j][i]);
|
|
pDC->SetTextColor(PenCols[i-1]);
|
|
pDC->TextOut((int)(OffsetX+Width+10.),((int) OffsetY)+14*i,lbls[i],(int) strlen(lbls[i]));
|
|
pDC->SelectObject(pOldPen); PlotPen.DeleteObject();
|
|
}
|
|
pDC->SetTextColor(0x00000000);
|
|
pDC->TextOut(200,(int) (OffsetY+Height+30),lbls[0],(int) strlen(lbls[0]));
|
|
k=(int)((HiY-LoY)/dy + 0.5);
|
|
if(k<4){
|
|
dy/=2.;
|
|
k=(int)((HiY-LoY)/dy + 0.5);
|
|
}
|
|
if(k==0) k++;
|
|
|
|
pDC->SetTextAlign(TA_RIGHT);
|
|
for(i=0;i<=k;i++){
|
|
pDC->MoveTo((int) OffsetX,(i*(int)Height)/k +(int) OffsetY);
|
|
pDC->LineTo((int) OffsetX-5,(i*(int) Height)/k+ (int) OffsetY);
|
|
sprintf(s,"%.4g",HiY-((double) i)*dy);
|
|
pDC->TextOut(((int) OffsetX)-10,(i*(int)Height)/k +(int) OffsetY-6,s,(int) strlen(s));
|
|
}
|
|
k=(int)((HiX-LoX)/dx );
|
|
if(k<4){
|
|
dx/=2.;
|
|
k=(int)((HiX-LoX)/dx );
|
|
}
|
|
d=( ((double) Width) * dx/ (HiX-LoX));
|
|
pDC->SetTextAlign(TA_CENTER);
|
|
for(i=0;i<=k;i++){
|
|
pDC->MoveTo((int) (((double) i)*d + OffsetX),(int) (OffsetY+Height));
|
|
pDC->LineTo((int) (((double) i)*d + OffsetX),(int) (OffsetY+Height)+5);
|
|
sprintf(s,"%.4g",LoX+((double) i)*dx);
|
|
pDC->TextOut((int)(((double) i)*d + OffsetX),(int) OffsetY+(int)Height+10,s,(int) strlen(s));
|
|
}
|
|
pDC->SetTextAlign(TA_LEFT);
|
|
|
|
|
|
pDC->SelectObject(pOldFont);
|
|
}
|
|
|
|
BOOL CXYPlot::ToDisk(int fileformat, CString ToFile)
|
|
{
|
|
FILE *fp;
|
|
int i,j;
|
|
CString dest_name;
|
|
|
|
if((NumCols==0) || (NumRows==0)){
|
|
if (ToFile=="") MsgBox("No data to write to disk.");
|
|
return FALSE;
|
|
}
|
|
|
|
if (ToFile=="")
|
|
{
|
|
CFileDialog *fname_dia=new CFileDialog(
|
|
FALSE,
|
|
"txt | * ",
|
|
dest_name,
|
|
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
|
|
"Text Files (*.txt) | *.txt; *.TXT | All Files (*.*) | *.*||",
|
|
NULL);
|
|
|
|
if(fname_dia->DoModal()==IDCANCEL){
|
|
delete[] fname_dia;
|
|
return FALSE;
|
|
}
|
|
|
|
dest_name=fname_dia->GetPathName();
|
|
|
|
delete[] fname_dia;
|
|
}
|
|
else dest_name=ToFile;
|
|
|
|
if((fp=fopen(dest_name,"wt"))!=NULL){
|
|
if (fileformat==0){
|
|
for(i=0;i<NumCols;i++)
|
|
fprintf(fp,"%% Column %i: %s\n",i,lbls[i]);
|
|
for(i=0;i<NumRows;i++){
|
|
for(j=0;j<NumCols;j++)
|
|
fprintf(fp,"%.8e ",M[i][j]);
|
|
fprintf(fp,"\n");
|
|
}
|
|
}
|
|
if (fileformat==1){
|
|
for(i=0;i<NumRows;i++){
|
|
for(j=0;j<NumCols;j++)
|
|
fprintf(fp,"%.8e ",M[i][j]);
|
|
fprintf(fp,"\n");
|
|
}
|
|
}
|
|
if (fileformat==2){
|
|
double x;
|
|
int n;
|
|
for(i=0;i<NumCols;i++)
|
|
fprintf(fp,"(* Column %i: %s *)\n",i,lbls[i]);
|
|
fprintf(fp,"{");
|
|
for(i=0;i<NumRows;i++){
|
|
fprintf(fp,"{");
|
|
for(j=0;j<NumCols;j++){
|
|
if (M[i][j]==0){
|
|
n=0;
|
|
x=0;
|
|
}
|
|
else{
|
|
n=(int) floor(log10(fabs(M[i][j])));
|
|
x=M[i][j]/pow((double)10,(double) n);
|
|
}
|
|
fprintf(fp,"%.8f*^%i",x,n);
|
|
if(j < (NumCols-1)) fprintf(fp,",");
|
|
else fprintf(fp,"}");
|
|
}
|
|
if(i < (NumRows-1)) fprintf(fp,",\n");
|
|
else fprintf(fp,"}\n");
|
|
}
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
if(ToFile=="")
|
|
{
|
|
CString OutMsg="Output written to "+ dest_name;
|
|
AfxMessageBox(OutMsg,MB_ICONINFORMATION);
|
|
}
|
|
}
|
|
else{
|
|
if (ToFile=="") MsgBox("Couldn't open output file");
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|