要处理一个数据,规格如下,是从EXCLE复制过来的,横轴是时间,纵轴是高度h 3 4 5 6 7 8 12.00
0.06 2.68E+07 2.50E+07 2.63E+07 2.66E+07 2.12E+07 1.22E+07 3835000.00
0.066 3.43E+07 3.22E+07 3.38E+07 3.41E+07 2.71E+07 1.57E+07 4967000.00
0.072 4.23E+07 4.00E+07 4.18E+07 4.21E+07 3.34E+07 1.95E+07 6188000.00
0.078 5.08E+07 4.82E+07 5.03E+07 5.06E+07 4.00E+07 2.35E+07 7477000.00
0.084 5.96E+07 5.69E+07 5.91E+07 5.96E+07 4.70E+07 2.78E+07 8817000.00
0.09 6.87E+07 6.59E+07 6.84E+07 6.88E+07 5.42E+07 3.22E+07 10200000.00
1147程序主要代码如下:主要的思路就是找到数据中的最大和最小值,然后用她们的差值除以色阶,得到阶率,就是(MAX-MIN)/INDEX(INDEX=1147,static COLORREF Colors[1148];)这样,再通过插值可以算出两个时间间隔之间数据,并可以算出他们对应的像素,从而使用SETPIEXL画图。现在的问题是,画的图效果不太好,我估计有两个原因,一个是插值效果不好,另一个是SETPIEXL不好用。大家能不能帮忙想想如何改进呢?
还有个问题是,如果插值太多的话,画出来的图,横轴就太长了,怎么才能不管画多大的图,都是固定的大小输出呢?谢谢了,不胜感激!
CDC* pDC = pwnd->GetWindowDC();
float temp,max,min;
int indel=1147;
temp=m_rrpr[0][0];
int InitValue=0;
int x_left=50,y_top=750; //绘图起点??
int x_width=800,y_height=500;//图像区域大小500,500//x_width控制X轴的长度
int x_jiange,y_jiange;
height=1400; //height,y_height 联合控制在图屏幕的大小
double y_range=height*m_JuLiFengBianLv/1000;
x_jiange=int(x_width/m_CeLiangShiJian-1);
y_jiange=int(y_height/(y_range+0.000000000001));
float m_pingju;
/**************
5-19 双二次插值,和移动平均 算法
**************/
//最大值
for(int i=1;i<m_CeLiangShiJian+1;i++)
for(int j=m_QiShiShuJu;j<m_ZhongZhiShuJU;j++)
{
if(temp<m_rrpr[i][j])
{
temp=m_rrpr[i][j];
}
}
max=temp;
//求最小值
temp=m_rrpr[0][0];
for(i=1;i<m_CeLiangShiJian+1;i++)
for(j=m_QiShiShuJu;j<m_ZhongZhiShuJU;j++)
{
if(temp>m_rrpr[i][j])
{
temp=m_rrpr[i][j];
}
}
min=temp;
step=(max-min)/indel; //分辨率 每一阶像素所占的点范围
//双线性插值算法
float nx11,nx12,nx21,nx22,Red1,Red2;
for(i=1;i<m_CeLiangShiJian+1;i++)
{
for(j=m_QiShiShuJu;j<m_ZhongZhiShuJU;j++) //双线性插值
{
nx11=m_rrpr[i][j];
nx12=m_rrpr[i+1][j];
for(int k=0;k<x_jiange;k++)
{
Red1=nx11+(nx12-nx11)*k/(x_jiange); //平滑过程
for(int m=0;m<1;m++)
{
z=Red1+(Red2-Red1)*m/1.0;
z=z*m_TiaoZhengXiShu;
index=(int)((z-InitValue)/(step+0.0000000000001));
index=abs(index);
if(index>1147)
{ index=1147;//依据C++BUILBUDER上第一页的INDEX1取值
}
if(index<0)
{
index=0;
}
if(index>=893)
{
Colors[index]=RGB(255,1148-index,0); //红 橙 黄
}
if((index>=638)&&(index<893))
{
Colors[index]=RGB(index-638,255,0); // 绿 草绿 黄
}
if((index>=383)&&(index<638))
{
Colors[index]=RGB(0,255,638-index); // 绿 青绿 青蓝
}
if((index>=128)&&(index<383))
{
Colors[index]=RGB(0,index-128,255); // 深蓝 浅蓝 青蓝
}
if((index>=0)&&(index<128))
{
Colors[index]=RGB(128-index,0,255); //深蓝 紫
}
pDC->SetPixel(i*x_jiange+k+x_left,
y_top-j*y_height/height,Colors[index]);
}
}
}
}
0.06 2.68E+07 2.50E+07 2.63E+07 2.66E+07 2.12E+07 1.22E+07 3835000.00
0.066 3.43E+07 3.22E+07 3.38E+07 3.41E+07 2.71E+07 1.57E+07 4967000.00
0.072 4.23E+07 4.00E+07 4.18E+07 4.21E+07 3.34E+07 1.95E+07 6188000.00
0.078 5.08E+07 4.82E+07 5.03E+07 5.06E+07 4.00E+07 2.35E+07 7477000.00
0.084 5.96E+07 5.69E+07 5.91E+07 5.96E+07 4.70E+07 2.78E+07 8817000.00
0.09 6.87E+07 6.59E+07 6.84E+07 6.88E+07 5.42E+07 3.22E+07 10200000.00
1147程序主要代码如下:主要的思路就是找到数据中的最大和最小值,然后用她们的差值除以色阶,得到阶率,就是(MAX-MIN)/INDEX(INDEX=1147,static COLORREF Colors[1148];)这样,再通过插值可以算出两个时间间隔之间数据,并可以算出他们对应的像素,从而使用SETPIEXL画图。现在的问题是,画的图效果不太好,我估计有两个原因,一个是插值效果不好,另一个是SETPIEXL不好用。大家能不能帮忙想想如何改进呢?
还有个问题是,如果插值太多的话,画出来的图,横轴就太长了,怎么才能不管画多大的图,都是固定的大小输出呢?谢谢了,不胜感激!
CDC* pDC = pwnd->GetWindowDC();
float temp,max,min;
int indel=1147;
temp=m_rrpr[0][0];
int InitValue=0;
int x_left=50,y_top=750; //绘图起点??
int x_width=800,y_height=500;//图像区域大小500,500//x_width控制X轴的长度
int x_jiange,y_jiange;
height=1400; //height,y_height 联合控制在图屏幕的大小
double y_range=height*m_JuLiFengBianLv/1000;
x_jiange=int(x_width/m_CeLiangShiJian-1);
y_jiange=int(y_height/(y_range+0.000000000001));
float m_pingju;
/**************
5-19 双二次插值,和移动平均 算法
**************/
//最大值
for(int i=1;i<m_CeLiangShiJian+1;i++)
for(int j=m_QiShiShuJu;j<m_ZhongZhiShuJU;j++)
{
if(temp<m_rrpr[i][j])
{
temp=m_rrpr[i][j];
}
}
max=temp;
//求最小值
temp=m_rrpr[0][0];
for(i=1;i<m_CeLiangShiJian+1;i++)
for(j=m_QiShiShuJu;j<m_ZhongZhiShuJU;j++)
{
if(temp>m_rrpr[i][j])
{
temp=m_rrpr[i][j];
}
}
min=temp;
step=(max-min)/indel; //分辨率 每一阶像素所占的点范围
//双线性插值算法
float nx11,nx12,nx21,nx22,Red1,Red2;
for(i=1;i<m_CeLiangShiJian+1;i++)
{
for(j=m_QiShiShuJu;j<m_ZhongZhiShuJU;j++) //双线性插值
{
nx11=m_rrpr[i][j];
nx12=m_rrpr[i+1][j];
for(int k=0;k<x_jiange;k++)
{
Red1=nx11+(nx12-nx11)*k/(x_jiange); //平滑过程
for(int m=0;m<1;m++)
{
z=Red1+(Red2-Red1)*m/1.0;
z=z*m_TiaoZhengXiShu;
index=(int)((z-InitValue)/(step+0.0000000000001));
index=abs(index);
if(index>1147)
{ index=1147;//依据C++BUILBUDER上第一页的INDEX1取值
}
if(index<0)
{
index=0;
}
if(index>=893)
{
Colors[index]=RGB(255,1148-index,0); //红 橙 黄
}
if((index>=638)&&(index<893))
{
Colors[index]=RGB(index-638,255,0); // 绿 草绿 黄
}
if((index>=383)&&(index<638))
{
Colors[index]=RGB(0,255,638-index); // 绿 青绿 青蓝
}
if((index>=128)&&(index<383))
{
Colors[index]=RGB(0,index-128,255); // 深蓝 浅蓝 青蓝
}
if((index>=0)&&(index<128))
{
Colors[index]=RGB(128-index,0,255); //深蓝 紫
}
pDC->SetPixel(i*x_jiange+k+x_left,
y_top-j*y_height/height,Colors[index]);
}
}
}
}
还有个问题是,如果插值太多的话,画出来的图,横轴就太长了,怎么才能不管画多大的图,都是固定的大小输出呢?------------只要使用一个常数表示屏幕中你想设置的图形的宽度,如int const nWidth=2000; 然后根据你的横轴的数据量(应该是项数吧?)来等分出一个值,或者叫比例尺或转换率。这样来画就可以了。而且你说的效果不太好,我都没弄明白如何的效果不太好?你希望的效果是如何的。这个说清楚一些,必要时上传个图我想可以帮助大家对你的要求的理解。而且你要的这个图好像也是有现成控件可以实现的。你只要将转换后的值赋给它就可以了。不过还是涉及到插值的问题(你需要向它提供的是计算后的值)。
数据没给清楚,重新写一下,呵呵。对不住了
3 4 5 6 7 8 9
2.68E+07 2.50E+07 2.63E+07 2.66E+07 2.12E+07 1.22E+07 3835000.00
3.43E+07 3.22E+07 3.38E+07 3.41E+07 2.71E+07 1.57E+07 4967000.00
. . . . . . . .
. . . . . . .
. . . . . . .
这样应当没问题了吧
横轴太长这个问题还有个情况是:如果横轴的数据点多呢?怎么在固定的区域画出来?比如9完了还有10,11,这样按照大哥的方法还是不行吧。(大哥的方法是固定3,4,5,6,7,.....的插值点数,对吧)再比如,如果纵轴的点数更多点呢?这样用SETPIEXL画的图,不是很大了么?多谢指教。呵呵
指向数据区的指针,当然用你自己定义的数据类型,long numbers是要绘制的数据的个数。
void CTestDlg::DrawCurve(CDC* dc,stress_time* pdata,long numbers)
{
POINT vector; //绘图区左上角坐标
vector.x=40;
vector.y=20;
//#define bitsOfwidth 500 //绘图区宽度
//#define bitsOfheight 300 //绘图区高度
/*************************************数据准备*****************************************/
float maxStress,minStress,maxTimer,minTimer;
maxStress=pdata->m_stress;
minStress=pdata->m_stress;
maxTimer=pdata->m_timer;
minTimer=pdata->m_timer;
struct point{float x;float y;};
point data[bitsOfwidth];
for(int i=0;i<bitsOfwidth;i++)
{
data[i].x=(pdata+long(i*numbers/bitsOfwidth))->m_timer;
data[i].y=(pdata+long(i*numbers/bitsOfwidth))->m_stress;
if(data[i].x>maxTimer)maxTimer=data[i].x;
if(data[i].x<minTimer)minTimer=data[i].x;
if(data[i].y>maxStress)maxStress=data[i].y;
if(data[i].y<minStress)minStress=data[i].y;
}
POINT position[bitsOfwidth];
for(i=0;i<bitsOfwidth;i++)
{
position[i].x=long((data[i].x-minTimer)*bitsOfwidth/(maxTimer-minTimer)+vector.x);
position[i].y=long(bitsOfheight-(data[i].y-minStress)*bitsOfheight/(maxStress-minStress)+vector.y);
}
/**************************************************************************************//*************************************背景绘制*****************************************/
CPen* oldpen;
CPen RedPen(PS_SOLID,1,RGB(250,0,0));
CPen GreenPen(PS_SOLID,1,RGB(0,200,0));
CPen BluePen(PS_SOLID,1,RGB(100,100,0));
RECT rect;
rect.bottom=vector.y+bitsOfheight+40;
rect.top=0;
rect.left=0;
rect.right=vector.x+bitsOfwidth+20;
CBrush BlueBrush(RGB(200,200,200));
dc->FillRect(&rect,&BlueBrush);
oldpen=dc->SelectObject(&GreenPen);
dc->MoveTo(vector);
dc->LineTo(vector.x,vector.y+bitsOfheight);
dc->LineTo(vector.x+bitsOfwidth,vector.y+bitsOfheight);
dc->LineTo(vector.x+bitsOfwidth,vector.y);
dc->LineTo(vector);
dc->SelectObject(&BluePen);
for(i=0;i<9;i++)
{
dc->MoveTo(vector.x,vector.y+(i+1)*bitsOfheight/10);
dc->LineTo(vector.x+bitsOfwidth,vector.y+(i+1)*bitsOfheight/10);
dc->MoveTo(vector.x+(i+1)*bitsOfwidth/10,vector.y);
dc->LineTo(vector.x+(i+1)*bitsOfwidth/10,vector.y+bitsOfheight);
}
dc->SetTextColor(RGB(0,0,250));
dc->SetBkMode(TRANSPARENT);
long x,y;
int l;
char st[30];
for(i=0;i<11;i++)
{
sprintf(st,"%.1f",minTimer+i*(maxTimer-minTimer)/10);
l=strlen(st);
y=vector.y+bitsOfheight+10;
x=vector.x+i*bitsOfwidth/10-l*3;
dc->TextOut(x,y,st);
}
for(i=0;i<11;i++)
{
sprintf(st,"%.1f",minStress+i*(maxStress-minStress)/10);
l=strlen(st);
y=vector.y+bitsOfheight-(i*bitsOfheight/10)-10;
x=vector.x-l*8;
dc->TextOut(x,y,st);
}
/**************************************************************************************//*************************************曲线绘制*****************************************/
dc->SelectObject(&RedPen);
for(i=0;i<(bitsOfwidth-1);i++)
{
dc->MoveTo(position[i]);
dc->LineTo(position[i+1]);
} dc->SelectObject(oldpen);
}