320 lines
8.4 KiB
C++
320 lines
8.4 KiB
C++
#include <math.h>
|
||
#include <cassert>
|
||
#include <QApplication>
|
||
#include <QDebug>
|
||
#include "MemRdwt.h"
|
||
#include "DrawNrad.h"
|
||
|
||
#define MAX_ARM 100 // 最大臂数
|
||
#define MAX_HORZ_GRID 20 // 最大插值点数
|
||
|
||
extern double GetData(int RepCode,char *buffer);
|
||
|
||
CDrawNrad::CDrawNrad(QMyCustomPlot *myCustomPlot, QString strSlfName, QString csCurve)
|
||
{
|
||
m_myCustomPlot = myCustomPlot;
|
||
|
||
//
|
||
m_PointNum=0;
|
||
m_LeftVal=30;
|
||
m_RightVal=65;
|
||
|
||
m_crHorzLine=qRgb(0,0,0);
|
||
m_crVertLine=qRgb(0,0,0);
|
||
m_nHorzLineWidth = 1;
|
||
m_nVertLineWidth = 1;
|
||
m_nHorzGrid = 0;
|
||
m_nArm = 36;
|
||
m_iStartArmPos=1;
|
||
m_iEndArmPos=11;
|
||
m_nFrac = 0;
|
||
|
||
m_D3Angle = 10;
|
||
m_iDoor = 0; // 门槛值
|
||
m_nAmp = 128;
|
||
|
||
m_nColorNum = 32;
|
||
|
||
m_flWjMaxFactor = 0.6;
|
||
m_flWjMinFactor = 0.5;
|
||
m_flVFactor = 0.8; //椭圆纵向半径占横向半径比例
|
||
}
|
||
|
||
CDrawNrad::~CDrawNrad(void)
|
||
{
|
||
|
||
}
|
||
|
||
void CDrawNrad::ReadData(QString strSlfName, QString csCurve)
|
||
{
|
||
if(strSlfName.isEmpty())return;
|
||
|
||
CMemRdWt mrw;
|
||
m_PointNum = 0 ;
|
||
char strFracTable[256];
|
||
int i,iIndex,iIndex2,nCount;
|
||
m_nArm = 1;
|
||
memset(&WaveInfo,0x00,sizeof(Slf_WAVE));
|
||
WaveInfo.ArrayNum = 0;
|
||
WaveInfo.TimeLevel = 0;
|
||
WaveInfo.TimeSamples = 0;
|
||
if ( mrw.Open(strSlfName.toStdString().c_str()) ) // 打开井文件
|
||
{
|
||
iIndex = mrw.OpenWave(csCurve.toStdString().c_str());
|
||
if (iIndex >= 0)
|
||
{
|
||
mrw.GetWaveInfo(iIndex,&WaveInfo);
|
||
m_SDep = WaveInfo.StartDepth;
|
||
m_EDep = WaveInfo.EndDepth;
|
||
m_Rlev = WaveInfo.DepLevel;
|
||
m_nSamples = WaveInfo.TimeSamples;
|
||
m_flRlev2 = WaveInfo.TimeLevel;
|
||
m_PointNum = (float)(fabs((m_EDep-m_SDep)/m_Rlev+0.5));
|
||
m_nArm = WaveInfo.TimeSamples;
|
||
}
|
||
mrw.CloseWave(iIndex);
|
||
//vVdl.vchar=m_Value;
|
||
mrw.Close(); //关闭井文件
|
||
}
|
||
}
|
||
|
||
void CDrawNrad::DrawNrad(QString strSlfName, QString csCurve)
|
||
{
|
||
if(strSlfName.isEmpty()) return;
|
||
if(m_nHorzLineWidth<=0)m_nHorzLineWidth = 1;
|
||
if(m_nVertLineWidth<=0)m_nVertLineWidth = 1;
|
||
float sdep,edep,flDepthScale,tempf;
|
||
float dep;
|
||
float x,y;
|
||
int i,j,k,nPointNum,mOffset =0;
|
||
int iIndex,npoint;
|
||
CMemRdWt mrw;
|
||
QPen pPen;
|
||
|
||
QPointF pt[MAX_ARM*MAX_HORZ_GRID];
|
||
QPointF **ptCal;//[2000][42];
|
||
float *Data,*DataTo; // 原始数据、插值后数据
|
||
float flScale[MAX_ARM*MAX_HORZ_GRID],flStep;
|
||
float flSin[MAX_ARM*MAX_HORZ_GRID],flCos[MAX_ARM*MAX_HORZ_GRID];
|
||
int nDrawArm,offsetX; // 插值前绘制的臂数
|
||
int nDrawArm2; // 插值后的臂数
|
||
int centerX,centerY ,nWidth ;
|
||
float xspeed;
|
||
float angle,ls1,ls2;
|
||
int r;
|
||
int iArmPos[MAX_ARM];
|
||
int nMid;
|
||
|
||
// 计算显示深度
|
||
tempf = (m_EDep - m_SDep)/m_Rlev+0.5;
|
||
nPointNum = tempf+1;
|
||
if ( nPointNum <= 1)
|
||
return ;
|
||
if ( m_nArm < 2)
|
||
return ;
|
||
if(m_iStartArmPos >= m_nArm) m_iStartArmPos = m_nArm-1;
|
||
|
||
// 初始化
|
||
int iMyWidth = m_myCustomPlot->axisRect(0)->width();
|
||
centerX = (iMyWidth+0)/2.0;
|
||
centerY = 0;
|
||
nWidth = iMyWidth;
|
||
// 最大外径宽度
|
||
tempf = m_flWjMaxFactor*nWidth/2;
|
||
r = tempf;
|
||
// 最大外径与最小外径差,即井径曲线的显示范围
|
||
tempf = (m_flWjMaxFactor-m_flWjMinFactor)*nWidth/2;
|
||
offsetX = tempf;
|
||
|
||
ls1 = nWidth*m_flWjMinFactor/2;
|
||
ls2 = nWidth*m_flWjMaxFactor/2;
|
||
|
||
// 统计需要显示井径曲线的序号
|
||
if ( m_iStartArmPos < m_iEndArmPos )
|
||
{
|
||
nDrawArm = m_iEndArmPos - m_iStartArmPos +1;
|
||
if ( nDrawArm > m_nArm )
|
||
nDrawArm = m_nArm;
|
||
for (i=0; i<nDrawArm; i++)
|
||
{
|
||
iArmPos[i] = m_iStartArmPos + i-1; // m_iStartArmlPos:从1开始计数
|
||
}
|
||
}
|
||
else
|
||
{
|
||
nDrawArm = (m_nArm-m_iStartArmPos)+ m_iEndArmPos +1;
|
||
if ( nDrawArm > m_nArm )
|
||
nDrawArm = m_nArm;
|
||
for (i=0; i<nDrawArm; i++)
|
||
{
|
||
if ( i <= m_nArm-m_iStartArmPos )
|
||
iArmPos[i] = m_iStartArmPos + i - 1; // m_iStartArmlPos:从1开始计数
|
||
else
|
||
iArmPos[i] = i-(m_nArm-m_iStartArmPos)-1;
|
||
}
|
||
}
|
||
if ( nDrawArm < 2 )
|
||
return ;
|
||
// 插值后的数据点数
|
||
nDrawArm2 = nDrawArm + (nDrawArm-1)*m_nHorzGrid;
|
||
nMid = nDrawArm2/2;
|
||
// 计算显示井径曲线的sin数值、所占宽度
|
||
angle = 3.*3.1415926/2;
|
||
xspeed = (3.1415926/(nDrawArm2-1)); // 半圆
|
||
|
||
// 方法1:使用等间距绘制
|
||
x = -r;
|
||
ls1 = (2*r-nDrawArm2*offsetX)/(nDrawArm2-1);
|
||
for (i=0;i<nDrawArm2; i++)
|
||
{
|
||
// 方法1
|
||
x = sin(angle) * r;
|
||
y = cos(angle) * r*m_flVFactor;
|
||
flCos[i] = cos(angle);
|
||
flSin[i] = sin(angle);
|
||
|
||
pt[i].setX(centerX + x);//pt[i].x = centerX + x;
|
||
pt[i].setY(centerY + y);//pt[i].y = centerY + y;
|
||
angle += xspeed;
|
||
}
|
||
x = pt[nMid].x();
|
||
|
||
|
||
// 显示时的比例
|
||
for (i=0;i<nDrawArm2; i++)
|
||
{
|
||
tempf = fabs(offsetX * flSin[i]);
|
||
ls1 = pt[i].x()+offsetX/2;
|
||
ls1 = ls1-tempf/2;
|
||
if (fabs(flSin[0]) < 0.00001 )
|
||
flScale[i] = 0;
|
||
else
|
||
flScale[i] = (m_RightVal-m_LeftVal)/tempf;
|
||
|
||
pt[i].setX(ls1);//pt[i].x = ls1; // 校正边界
|
||
}
|
||
// 按中心点位置校正坐标
|
||
x = x-pt[nMid].x();
|
||
for (i=0;i<nDrawArm2; i++)
|
||
{
|
||
pt[i].setX(pt[i].x()+x) ; // 校正边界
|
||
}
|
||
|
||
|
||
mOffset =0;
|
||
iIndex=-1;
|
||
if ( mrw.Open(strSlfName.toStdString().c_str()) ) // 打开井文件
|
||
{
|
||
iIndex = mrw.OpenWave(csCurve.toStdString().c_str());
|
||
}
|
||
|
||
// 1个阵列 40条曲线
|
||
char *value=new char[(m_nSamples+1)*WaveInfo.CodeLen];
|
||
Data = new float[nDrawArm+1];
|
||
if ( m_nHorzGrid > 0 )
|
||
DataTo = new float[(nDrawArm+nDrawArm*m_nHorzGrid)+1];
|
||
ptCal = new QPointF *[nPointNum];
|
||
for (i=0; i<nPointNum; i++)
|
||
ptCal[i] = new QPointF[nDrawArm+nDrawArm*m_nHorzGrid];
|
||
|
||
npoint = 0;
|
||
flStep = 1./(m_nHorzGrid +1.);
|
||
// 注意映射方式
|
||
for (i = 0; i < nPointNum ; i++)
|
||
{
|
||
dep=m_SDep+i*m_Rlev;
|
||
y = dep;
|
||
|
||
if (iIndex >= 0)
|
||
{
|
||
mrw.ReadWave(iIndex,dep,1,(void *)value);
|
||
}
|
||
else
|
||
memset(value,0,m_nSamples*WaveInfo.DepLevel);
|
||
// 需要绘制的井径曲线
|
||
for (j=0; j<nDrawArm; j++)
|
||
Data[j] = GetData(WaveInfo.RepCode,(char *)&value[iArmPos[j]*WaveInfo.CodeLen]);
|
||
|
||
// 插值
|
||
if ( m_nHorzGrid == 0 )
|
||
DataTo = Data;
|
||
else
|
||
{
|
||
for (j=0; j<nDrawArm-1; j++)
|
||
{
|
||
DataTo[j*(1+m_nHorzGrid)] = Data[j];
|
||
DataTo[(j+1)*(1+m_nHorzGrid)] = Data[j+1];
|
||
for (k=0; k<m_nHorzGrid; k++)
|
||
{
|
||
DataTo[j*(1+m_nHorzGrid)+k+1] = Data[j] + flStep*(k+1) *(Data[j+1]-Data[j]);
|
||
}
|
||
}
|
||
}
|
||
for (j=0; j<nDrawArm2; j++)
|
||
{
|
||
// 按与等横向间距差值绘制
|
||
|
||
// 等角度绘制
|
||
if ( j< nMid )
|
||
{
|
||
tempf = pt[j].x() -(DataTo[j]-m_RightVal)/flScale[j];
|
||
}
|
||
else
|
||
{
|
||
if ( j > nMid )
|
||
{
|
||
tempf = pt[j].x() +(DataTo[j]-m_LeftVal)/flScale[j];
|
||
}
|
||
else
|
||
{
|
||
tempf= pt[j].x();
|
||
}
|
||
}
|
||
|
||
x = tempf;
|
||
// y坐标不计算,按采样间隔计算得来
|
||
tempf = y + pt[j].y();
|
||
|
||
ptCal[npoint][j].setX(x);
|
||
ptCal[npoint][j].setY(tempf);
|
||
}
|
||
npoint++;
|
||
}
|
||
// 绘制横线
|
||
QPointF *ptOld = new QPointF[nDrawArm2+1];
|
||
pPen.setColor(m_crHorzLine);
|
||
pPen.setWidth(m_nHorzLineWidth);
|
||
|
||
for (i=0;i<npoint; i+=m_nVertGrid)
|
||
{
|
||
for (j=0; j<nDrawArm2; j++)
|
||
ptOld[j] = ptCal[i][j];
|
||
|
||
//pDC->drawPolyline(ptOld,nDrawArm2);
|
||
|
||
}
|
||
|
||
delete [] ptOld;
|
||
// 绘制竖线
|
||
pPen.setColor(m_crVertLine);
|
||
pPen.setWidth(m_nVertLineWidth);
|
||
|
||
ptOld = new QPointF[npoint+1];
|
||
for (i=0;i<nDrawArm2; i++)
|
||
{
|
||
for (j=0; j<npoint; j++)
|
||
ptOld[j] = ptCal[j][i];
|
||
//pDC->drawPolyline(ptOld,npoint);
|
||
}
|
||
delete [] ptOld;
|
||
// 清理、释放内存
|
||
delete [] value;
|
||
delete [] Data ;
|
||
if ( m_nHorzGrid > 0 )
|
||
delete [] DataTo;
|
||
|
||
for (i=0; i<nPointNum; i++)
|
||
delete [] ptCal[i] ;
|
||
delete [] ptCal;
|
||
}
|