logplus/logPlus/DrawNrad.cpp

378 lines
11 KiB
C++
Raw Normal View History

2026-01-12 17:31:21 +08:00
#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; //椭圆纵向半径占横向半径比例
2026-01-13 11:20:03 +08:00
m_nVertGrid = 20; //纵向网格间隔
ReadData(strSlfName, csCurve);
DrawNrad(strSlfName, csCurve);
2026-01-12 17:31:21 +08:00
}
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;
2026-01-13 11:20:03 +08:00
2026-01-12 17:31:21 +08:00
// y坐标不计算按采样间隔计算得来
2026-01-13 11:20:03 +08:00
tempf = m_myCustomPlot->xAxis->pixelToCoord( m_myCustomPlot->xAxis->coordToPixel(-y)+pt[j].y());//y + pt[j].y();
2026-01-12 17:31:21 +08:00
ptCal[npoint][j].setX(x);
ptCal[npoint][j].setY(tempf);
}
npoint++;
}
2026-01-13 11:20:03 +08:00
2026-01-12 17:31:21 +08:00
// 绘制横线
pPen.setColor(m_crHorzLine);
pPen.setWidth(m_nHorzLineWidth);
2026-01-13 11:20:03 +08:00
QPointF *ptOld = new QPointF[nDrawArm2+1];
2026-01-12 17:31:21 +08:00
for (i=0;i<npoint; i+=m_nVertGrid)
{
2026-01-13 11:20:03 +08:00
QVector<double> xVec, yVec;
2026-01-12 17:31:21 +08:00
for (j=0; j<nDrawArm2; j++)
2026-01-13 11:20:03 +08:00
{
2026-01-12 17:31:21 +08:00
ptOld[j] = ptCal[i][j];
2026-01-13 11:20:03 +08:00
xVec.append(ptOld[j].x());
yVec.append(ptOld[j].y());
}
2026-01-12 17:31:21 +08:00
2026-01-13 11:20:03 +08:00
for (j=0; j<nDrawArm2-1; j++)
{
QCPItemLine *qcpItemLine = new QCPItemLine(m_myCustomPlot);
qcpItemLine->start->setCoords(yVec[j], xVec[j]);
qcpItemLine->end->setCoords(yVec[j+1], xVec[j+1]);
qcpItemLine->setPen(pPen);
}
// {
// //
// m_myCustomPlot->addGraph();
// QString strLineName = "";
// if(strLineName=="")
// {
// strLineName = QString("曲线 %1").arg(m_myCustomPlot->graphCount());
// }
// m_myCustomPlot->graph()->setName(strLineName);
// m_myCustomPlot->graph()->setData(yVec, xVec);
// m_myCustomPlot->graph()->setLineStyle((QCPGraph::LineStyle)(QCPGraph::lsLine));//lsNone 曲线 lsLine
// m_myCustomPlot->graph()->setScatterStyle(QCPScatterStyle((QCPScatterStyle::ScatterShape)(QCPScatterStyle::ssDot)));//ssNone点ssDot
// //
// QPen graphPen;
// graphPen.setColor(m_crHorzLine);
// graphPen.setWidthF(m_nHorzLineWidth);
// graphPen.setStyle(Qt::SolidLine);//实线
// m_myCustomPlot->graph()->setPen(graphPen);
// }
2026-01-12 17:31:21 +08:00
2026-01-13 11:20:03 +08:00
}
2026-01-12 17:31:21 +08:00
delete [] ptOld;
2026-01-13 11:20:03 +08:00
// 绘制竖线
2026-01-12 17:31:21 +08:00
ptOld = new QPointF[npoint+1];
for (i=0;i<nDrawArm2; i++)
{
2026-01-13 11:20:03 +08:00
QVector<double> xVec, yVec;
2026-01-12 17:31:21 +08:00
for (j=0; j<npoint; j++)
2026-01-13 11:20:03 +08:00
{
2026-01-12 17:31:21 +08:00
ptOld[j] = ptCal[j][i];
2026-01-13 11:20:03 +08:00
xVec.append(ptOld[j].x());
yVec.append(ptOld[j].y());
}
{
//
m_myCustomPlot->addGraph();
QString strLineName = "";
if(strLineName=="")
{
strLineName = QString("曲线 %1").arg(m_myCustomPlot->graphCount());
}
m_myCustomPlot->graph()->setName(strLineName);
m_myCustomPlot->graph()->setData(yVec, xVec);
m_myCustomPlot->graph()->setLineStyle((QCPGraph::LineStyle)(QCPGraph::lsLine));//lsNone 曲线 lsLine
m_myCustomPlot->graph()->setScatterStyle(QCPScatterStyle((QCPScatterStyle::ScatterShape)(QCPScatterStyle::ssDot)));//ssNone点ssDot
//
QPen graphPen;
graphPen.setColor(m_crVertLine);
graphPen.setWidthF(m_nVertLineWidth);
graphPen.setStyle(Qt::SolidLine);//实线
m_myCustomPlot->graph()->setPen(graphPen);
}
2026-01-12 17:31:21 +08:00
}
delete [] ptOld;
2026-01-13 11:20:03 +08:00
2026-01-12 17:31:21 +08:00
// 清理、释放内存
delete [] value;
delete [] Data ;
if ( m_nHorzGrid > 0 )
delete [] DataTo;
for (i=0; i<nPointNum; i++)
delete [] ptCal[i] ;
delete [] ptCal;
}