logplus/logPlus/DrawNrad.cpp
2026-01-12 17:31:21 +08:00

320 lines
8.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}