Matlab在数学计算与绘图方面有太多优势了,而当前项目用的是QT C++开发的软件,需求是QT软件将从其他渠道获取的数据输入到Matlab中进行运算、显示数据图(一般是数学关系图)。
主要的参考文章有:
参考第2片文章调通了,其中部分代码不全,自己就按原博主的matlab测试数据试着调完了。
两个地方调整:
在matlab中运行一下,我是另写了一个m文件来实现的
% 函数digraph(s,t,v):可在 s 和 t 中的对应节点之间创建边,并生成一个图
% s 和 t 都必须具有相同的元素数;这些节点必须都是从1开始的正整数,或都是字符串元胞数组。
fullLineS=[1 1 5 1 3 8 7 2 6 9 4 10 2 3 5 6 8 9];
fullLineT= [2 3 4 5 6 7 11 8 9 11 10 11 3 4 6 7 9 10 ];
v=[3 2 4 3 3 3 3 5 3];
dottedLineS=[1 2 3]; %虚线
dottedLineT=[2 3 4];
taskNum=9;
jobId=[ 2 1 3 3 1 2 2 1 3 ];
oper=[ 1 1 2 1 2 3 2 3 3 ];
iCriticalPathS=[5 8]; %关键路径
iCriticalPathT=[6 9];
select=1;
% 增加一行调用函数的代码
Matlab_Digraph(fullLineS, fullLineT, v, dottedLineS, dottedLineT, taskNum, jobId, oper, iCriticalPathS, iCriticalPathT, select);
在第四章编译和运行部分调整如下
#define MAXEDGE (18)
#define JOBNUM (9)
#define WORKPIECENUM (6)
const int criticalPathArcSize = 2;
void MainWindow::DrawDigraph_CP()
{
if (!Matlab_DigraphInitialize()) // 初始化,必须要使用
{
qDebug() << "add init failed.";
return;
}
int taskNum[2];
taskNum[0] = JOBNUM;
int workPieceNum = WORKPIECENUM;
int fullLineS[MAXEDGE] = {1, 1, 5, 1, 3, 8, 7, 2, 6, 9, 4, 10, 2, 3, 5, 6, 8, 9};
int fullLineT[MAXEDGE] = {2, 3, 4, 5, 6, 7, 11, 8, 9, 11, 10, 11, 3, 4, 6, 7, 9, 10};
int jobId[JOBNUM] = {2, 1, 3, 3, 1, 2, 2, 1, 3};
int oper[JOBNUM] = {1, 1, 2, 1, 2, 3, 2, 3, 3};
int macDurationTime[JOBNUM] = {3, 2, 4, 3, 3, 3, 3, 5, 3};
int dottedLineS[] = {1, 2, 3};
int dottedLineT[] = {2, 3, 4};
int iCriticalPathS[] = {5, 8};
int iCriticalPathT[] = {6, 9};
int select[] = {1};
mwArray in_fullLineS(1, MAXEDGE, mxDOUBLE_CLASS, mxREAL);
mwArray in_fullLineT(1, MAXEDGE, mxDOUBLE_CLASS, mxREAL);
mwArray in_jobId(1, taskNum[0], mxDOUBLE_CLASS, mxREAL);
mwArray in_oper(1, taskNum[0], mxDOUBLE_CLASS, mxREAL);
mwArray in_v(1, taskNum[0], mxDOUBLE_CLASS, mxREAL);
mwArray in_dottedLineS(1, MAXEDGE - workPieceNum - taskNum[0], mxDOUBLE_CLASS, mxREAL);
mwArray in_dottedLineT(1, MAXEDGE - workPieceNum - taskNum[0], mxDOUBLE_CLASS, mxREAL);
mwArray in_taskNum(1, 1, mxDOUBLE_CLASS, mxREAL);
mwArray in_iCriticalPathS(1, criticalPathArcSize, mxDOUBLE_CLASS, mxREAL);
mwArray in_iCriticalPathT(1, criticalPathArcSize, mxDOUBLE_CLASS, mxREAL);
mwArray in_select(1, 1, mxDOUBLE_CLASS, mxREAL);
in_fullLineS.SetData(fullLineS, MAXEDGE);
in_fullLineT.SetData(fullLineT, MAXEDGE);
in_jobId.SetData(jobId, taskNum[0]);
in_oper.SetData(oper, taskNum[0]);
in_v.SetData(macDurationTime, taskNum[0]);
in_dottedLineS.SetData(dottedLineS, MAXEDGE - workPieceNum - taskNum[0]);
in_dottedLineT.SetData(dottedLineT, MAXEDGE - workPieceNum - taskNum[0]);
in_taskNum.SetData(taskNum, 1);
in_iCriticalPathS.SetData(iCriticalPathS, criticalPathArcSize);
in_iCriticalPathT.SetData(iCriticalPathT, criticalPathArcSize);
in_select.SetData(select, 1);
Matlab_Digraph(in_fullLineS, in_fullLineT, in_v, in_dottedLineS, in_dottedLineT, in_taskNum, in_jobId, in_oper, in_iCriticalPathS, in_iCriticalPathT, in_select);
}
第一篇文章中的方法和其他这么多文章中类似,但我试了运行Init函数时会报错,有时间查一下是否因为要用Matlab x64。两篇文章在生成dll时方法不同,按理原理上一样。
后者指明使用C++ shared库,而前者默认应该是C接口的库。
后者直接使用m函数文件中自己的画图方法,C++只是传递数据,相当于绘图窗口是由Matlab库内部直接调用实现的。这更符合我当前项目的场景;
前者是只用了Matlab的函数计算,获取到数据后再使用QT的绘图插件来画图(整体性更好,但一方面我对这些插件不熟,另一方面更相信Matlab的强大绘图能力),有空可以学1,2个绘图插件对比对比。
如果库生成了,学习一下如何使用mwArray来传递数据应该就问题不大了。后面精将放在如何编写好的m函数,以及如何动态刷新绘图了。
再次感谢两位博主。