ProEssentials第100例SimpleScientificGraph,使用DLL单文档VC6.0实现

来源:互联网 发布:windows ftp命令用法 编辑:程序博客网 时间:2024/06/11 12:07

关于dll配置情况第000课,这里不再介绍,只增加了一个获取随机数的函数000课链接

本课链接

int CPEView::GetRandom(int a, int b){                //要取得[a,b)的随机整数,使用(rand() % (b-a))+ a (结果值含a不含b)。                  //要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a (结果值含a和b)。                 //要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1 (结果值不含a含b)。                 //得到a,b之间的随机整数         int i = (rand()%(b-a+1))+a;        return i;}

绘图函数如下

void CPEView::CreateSimpleSGraph(){//! 右键弹出菜单. //   //! Double Click to show customization dialog. //   //! Left-Click and drag to draw zoom box. Use popup memu or 'z' to undo zoom. //    // Simple example show the basics of a 科学图表对象. //   // Scientific Graph's contain both YData and XData and thus data   // is not plotted equally spaced as the graph object does.   RECT rect;   GetClientRect( &rect );   //窗口句柄=PEcreate(空间类型,风格,窗口矩形,窗口句柄,ID   m_hPE = PEcreate(PECONTROL_SGRAPH, WS_VISIBLE, &rect, m_hWnd, 1001);   if( m_hPE )   {       float fY;       float fX;       // 鼠标中建拖拽 //       PEnset(m_hPE, PEP_bMOUSEDRAGGINGX, TRUE);       PEnset(m_hPE, PEP_bMOUSEDRAGGINGY, TRUE);       // Enable Bar Glass Effect //       PEnset(m_hPE, PEP_bBARGLASSEFFECT, TRUE);       // 开启绘制模式坡度和倾斜风格        PEnset(m_hPE, PEP_nAREAGRADIENTSTYLE,  PEPGS_RADIAL_BOTTOM_RIGHT);       PEnset(m_hPE, PEP_nAREABEVELSTYLE, PEBS_MEDIUM_SMOOTH);       PEnset(m_hPE, PEP_nSPLINEGRADIENTSTYLE,  PEPGS_RADIAL_BOTTOM_RIGHT);       PEnset(m_hPE, PEP_nSPLINEBEVELSTYLE, PESBS_MEDIUM_SMOOTH);       // 子集数量和点数 4个集合,每个集合12个点        PEnset(m_hPE, PEP_nSUBSETS, 4);       PEnset(m_hPE, PEP_nPOINTS, 12);       for( int s=0; s<=3; s++ )//集合0-3       {           for( int p=0; p<=11; p++ )//第i个点 0-11           {                 fX = ((float) (p+1)) * 100.0F + ((float) GetRandom(2, 250)) / 50.0F;               PEvsetcellEx (m_hPE, PEP_faXDATA, s, p, &fX);//横轴坐标值               fY = ((float) (p+1) * 1.0F) + ((float)GetRandom(1, 250)) + 700.0F - ((float) (s * 140.0F)) + ((float) GetRandom(2, 250))/ 250.0F ;               PEvsetcellEx (m_hPE, PEP_faYDATA, s, p, &fY);//纵轴坐标值           }       }       // 设置DataShadows 显示阴影DS for DATASHADOWS       PEnset(m_hPE, PEP_nDATASHADOWS, PEDS_SHADOWS);       PEszset(m_hPE, PEP_szMAINTITLE, TEXT("示例数据"));       PEszset(m_hPE, PEP_szSUBTITLE, TEXT("")); // 无副标题       PEszset(m_hPE, PEP_szYAXISLABEL, TEXT("售出数量"));       PEszset(m_hPE, PEP_szXAXISLABEL, TEXT("月份"));       PEnset(m_hPE, PEP_bFOCALRECT, FALSE);       PEnset(m_hPE, PEP_bPREPAREIMAGES, TRUE);       PEnset(m_hPE, PEP_bCACHEBMP, TRUE);       PEnset(m_hPE, PEP_nPLOTTINGMETHOD, PEGPM_SPLINE);       PEnset(m_hPE, PEP_nGRIDLINECONTROL, PEGLC_BOTH);       PEnset(m_hPE, PEP_nGRIDSTYLE, PEGS_DOT);       PEnset(m_hPE, PEP_nALLOWZOOMING, PEAZ_HORZANDVERT);       PEnset(m_hPE, PEP_nZOOMSTYLE, PEZS_RO2_NOT);       //子集标签       PEvsetcell( m_hPE, PEP_szaSUBSETLABELS, 0, TEXT("陕西省"));       PEvsetcell( m_hPE, PEP_szaSUBSETLABELS, 1, TEXT("湖北省" ));       PEvsetcell( m_hPE, PEP_szaSUBSETLABELS, 2, TEXT("北京" ));       PEvsetcell( m_hPE, PEP_szaSUBSETLABELS, 3, TEXT("广东省" ));       // 子集颜色       DWORD dwArray[4] = { PERGB(128,198,0,0), PERGB(128, 0, 198, 198 ), PERGB(128, 198,198,0 ), PERGB(128, 0,198,0 ) };       PEvsetEx( m_hPE, PEP_dwaSUBSETCOLORS, 0, 4, dwArray, 0 );       //子集线型       int nLineTypes[] = { PELT_MEDIUMSOLID, PELT_MEDIUMSOLID, PELT_MEDIUMSOLID, PELT_MEDIUMSOLID };       PEvset(m_hPE, PEP_naSUBSETLINETYPES, nLineTypes, 4);       //子集点的类型       int nPointTypes[] = { PEPT_DOTSOLID, PEPT_UPTRIANGLESOLID, PEPT_SQUARESOLID, PEPT_DOWNTRIANGLESOLID };       PEvset(m_hPE, PEP_naSUBSETPOINTTYPES, nPointTypes, 4);       // Version 4.0 Features //       PEnset(m_hPE, PEP_bFIXEDFONTS, TRUE);       PEnset(m_hPE, PEP_bSIMPLEPOINTLEGEND, TRUE);       PEnset(m_hPE, PEP_bSIMPLELINELEGEND, TRUE);       PEnset(m_hPE, PEP_nLEGENDSTYLE, PELS_1_LINE);       PEnset(m_hPE, PEP_nMULTIAXISSTYLE, PEMAS_SEPARATE_AXES);       // Set Various Other Properties //       PEnset(m_hPE, PEP_bBITMAPGRADIENTMODE, TRUE);       PEnset(m_hPE, PEP_nQUICKSTYLE, PEQS_MEDIUM_NO_BORDER);       PEnset(m_hPE, PEP_nGRADIENTBARS, 8);       PEnset(m_hPE, PEP_nTEXTSHADOWS, PETS_BOLD_TEXT);       PEnset(m_hPE, PEP_bMAINTITLEBOLD, TRUE);       PEnset(m_hPE, PEP_bSUBTITLEBOLD, TRUE);       PEnset(m_hPE, PEP_bLABELBOLD, TRUE);       PEnset(m_hPE, PEP_bLINESHADOWS, TRUE);       PEnset(m_hPE, PEP_nFONTSIZE, PEFS_LARGE);       PEnset(m_hPE, PEP_bSCROLLINGHORZZOOM, TRUE);       PEnset(m_hPE, PEP_nDATAPRECISION, 1);       // Improves metafile export //       PEnset(m_hPE, PEP_nDPIX, 600);       PEnset(m_hPE, PEP_nDPIY, 600);       // Set Demo's RenderEngine to Gdi Plus //     //   CMDIFrameWnd* pWnd = (CMDIFrameWnd*) AfxGetApp()->GetMainWnd();     //  pWnd->SendMessage(WM_CHANGE_METAFILE, PEPLAYMETAFILEGDIPLUS );   }}

结果


这里有一点没弄明白,就是随机函数,如果改为如下,则基本上不变化,原因就在srand放在了循环里,而一次循环间隔不超过time的1秒钟,所以改正方法是每个程序srand只初始化一次就可以了,而且记住要在循环外面。

int CPEView::GetRandom(int a, int b){srand(time(0));    //以time为生成随机数的种子,以便随机数不重复int i = (rand()%(b-a+1))+a;return i;}


以下引用百度百科和百度知道

int rand(void)

函数说明 :因为rand的内部实现是用线性同余法做的,他不是真的随机数,只不过是因为其周期特别长,所以有一定的范围里可看成是随机的,rand()会返回一随机数值,范围在0至RAND_MAX 间。在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。rand ()产生的是假随机数字,每次执行时是相同的。若要不同,以不同的值来初始化它.初始化的函数就是srand()。

返回值:返回0至RAND_MAX之间的随机整数值,RAND_MAX的范围最少是在32767之间(int),即双字节(16位数)。若用unsigned int 双字节是65535,四字节是4294967295的整数范围。0~RAND_MAX每个数字被选中的机率是相同的。


范例:/* 产生介于1 到10 间的随机数值,此范例未设随机数种子,完整的随机数产生请参考srand()*/

#include<stdlib.h>main(){   int i,j;   for(i=0;i<10;i++)   {      j=1+(int)(10.0*rand()/(RAND_MAX+1.0));     printf("%d ",j);   }}
执行:

9 4 8 8 10 2 4 8 3 6

9 4 8 8 10 2 4 8 3 6 //再次执行仍然产生相同的随机数


srand(设置随机数种子)

表头文件:#include<stdlib.h>

定义函数:void srand (unsigned int seed);

函数说明:srand()用来设置rand()产生随机数时的随机数种子。

参数seed必须是个整数,通常可以利用geypid()或time(0)的返回值来当做seed。如果每次seed都设相同值,rand()所产生的随机数值每次就会一样。

范例

/* 产生介于1 到10 间的随机数值,此范例与执行结果可与rand()参照*/#include<time.h>#include<stdlib.h>main(){   int i,j;   srand((int)time(0));   for(i=0;i<10;i++)   {      j=1+(int)(10.0*rand()/(RAND_MAX+1.0));     printf(" %d ",j);   }}

执行:与rand范例比较

5 8 8 8 10 2 10 8 9 9

2 9 7 4 10 3 2 10 8 7

又或:用"int x = rand() % 100;"来生成 0 到 100 之间的随机数这种方法是不或取的,比较好的做法是:

 j=(int)(n*rand()/(RAND_MAX+1.0))产生一个0到n之间的随机数int main(void){   int i;   time_t t;   srand((unsigned) time(&t));   printf("Ten random numbers from 0 to 99\n\n");   for(i=0; i<10; i++)       printf("%d\n", rand() % 100);   return 0;}

补充一点就是srand这个函数一定要放在循环外面或者是循环调用的外面,否则的话得到的是相同的数字。

srand(time(NULL)) 这是调用time函数得到当前的时间, 用这个时间给随机设定个初始值。 这个事情一个程序里只需要做一次, 为什么要把它放在循环里? 如果放在循环里,因为运行速度比较快,都在同一秒内, 时间没变化, 所以总是用同一个数给它初始化, 自然得到的序列就是相同的.

 time

头文件:time.h

  函数原型:time_t time(time_t * timer)

  功能: 获取当前的系统时间,返回的结果是一个time_t类型,其实就是一个大整数,其值表示从CUT(Coordinated Universal Time)时间1970年1月1日00:00:00(称为UNIX系统的Epoch时间)到当前时刻的秒数然后调用localtime将time_t所表示的CUT时间转换为本地时间(我们是+8区,比CUT多8个小时)并转成struct tm类型,该类型的各数据成员分别表示年月日时分秒。