已经可以调用MATLAB,但可能代码有问题,MATLAB图像不出来,求能人赐教!
这是对vs的配置
这是C语言代码
#include "engine.h"
#include
#include
#include <string.h>
#include
int main()
{
Engine* ep;
mxArray* t = NULL, * l = NULL, * x = NULL, * y_fwd = NULL, * y_bwd = NULL, * y_res = NULL;
double* t_data, * l_data, * x_data;
double amp_fwd, freq_fwd, wavelen_fwd, amp_bwd, freq_bwd, wavelen_bwd;
int i, j, n;
// 连接到 MATLAB 引擎
if (!(ep = engOpen(NULL)))
{
fprintf(stderr, "无法连接到 MATLAB 引擎\n");
return EXIT_FAILURE;
}
// 创建 t 向量
t = mxCreateDoubleMatrix(1, 1001, mxREAL);
t_data = mxGetPr(t);
for (i = 0; i < 1001; i++)
{
t_data[i] = i * 0.1;
}
// 创建 l 向量
l = mxCreateDoubleScalar(10);
l_data = mxGetPr(l);
// 创建 x 向量
x = mxCreateDoubleMatrix(1, 101, mxREAL);
x_data = mxGetPr(x);
for (i = 0; i < 101; i++)
{
x_data[i] = i * (*l_data) / 200;
}
// 获取用户输入参数
printf("请输入正向波的振幅:\n");
scanf("%lf", &_fwd);
printf("请输入正向波的频率:\n");
scanf("%lf", &freq_fwd);
printf("请输入正向波的波长:\n");
scanf("%lf", &wavelen_fwd);
printf("请输入反向波的振幅:\n");
scanf("%lf", &_bwd);
printf("请输入反向波的频率:\n");
scanf("%lf", &freq_bwd);
printf("请输入反向波的波长:\n");
scanf("%lf", &wavelen_bwd);
// 循环每个时间点,计算波形并绘图
for (n = 0; n < 1001; n++)
{
y_fwd = mxCreateDoubleMatrix(1, 101, mxREAL);
y_bwd = mxCreateDoubleMatrix(1, 101, mxREAL);
y_res = mxCreateDoubleMatrix(1, 101, mxREAL);
for (j = 0; j < 101; j++)
{
*(mxGetPr(y_fwd) + j) = amp_fwd * sin(2 * 3.1416 * (t_data[n] * freq_fwd - x_data[j] / wavelen_fwd));
*(mxGetPr(y_bwd) + j) = amp_bwd * sin(2 * 3.1416 * (t_data[n] * freq_bwd + x_data[j] / wavelen_bwd));
*(mxGetPr(y_res) + j) = *(mxGetPr(y_fwd) + j) + *(mxGetPr(y_bwd) + j);
}
engEvalString(ep, "clf");
engEvalString(ep, "plot(x , y_fwd , 'r', x , y_bwd , 'b', x , y_res , 'g')");
engEvalString(ep, "title('波形合成')");
engEvalString(ep, "xlabel('位置')");
engEvalString(ep, "ylabel('振幅')");
engEvalString(ep, "legend('正向波', '反向波', '驻波')");
engEvalString(ep, "axis([0 10 -5 5])");
engEvalString(ep, "M(n) = getframe()");
mxGetPr(y_fwd);
mxGetPr(y_bwd);
mxGetPr(y_res);
mxDestroyArray(y_fwd);
mxDestroyArray(y_bwd);
mxDestroyArray(y_res);
}
// 关闭 MATLAB 引擎
mxDestroyArray(t);
mxDestroyArray(l);
mxDestroyArray(x);
engClose(ep);
return 0;
}
然后出来的是只有坐标轴,而且在不停闪,右上角有个矩形也在闪
可以在 Visual Studio 中通过使用 MATLAB 的 COM 功能来调用 MATLAB 引擎,从而实现在 VS 中绘制动态驻波图。以下是一些参考步骤:
#include <mex.h>
#include <engine.h>
#pragma comment(lib, "libmx.lib")
#pragma comment(lib, "libeng.lib")
Engine *ep; // 声明 MATLAB 引擎指针变量
if (!(ep = engOpen(NULL))) {
// 如果连接失败,则输出错误信息并退出程序
fprintf(stderr, "\nUnable to connect to MATLAB Engine\n");
return EXIT_FAILURE;
}
例如,以下示例代码使用 surf
函数绘制动态驻波图:
function [] = drawStandingWave()
x = linspace(-2*pi,2*pi,100);
t = 0:0.05:10*pi;
[X,T] = meshgrid(x,t);
Y = sin(X).*cos(T-X);
surf(X,Y,T);
end
// 调用 MATLAB 绘图函数
engEvalString(ep, "drawStandingWave();");
// 获取绘图窗口句柄
mxArray *hfigure = engGetVariable(ep, "gcf");
int figureHWnd = (int)mxGetScalar(mxGetProperty(hfigure, 0, "Number"));
// 设置绘图窗口为前台窗口
SetForegroundWindow((HWND)figureHWnd);
SetForegroundWindow
将 MATLAB 绘图窗口设置为前台窗口,即可在 VS 中显示动态驻波图。希望这些步骤能够帮到您!
该回答引用ChatGPT:根据您提供的代码,我看到一个问题是您没有给正向波和反向波的振幅赋值,而是给了一个未定义的变量 _fwd 和 _bwd。您需要将这两个变量改为 amp_fwd 和 amp_bwd,并且在用户输入时也需要修改相应的变量名。
另外,您需要在循环开始前初始化变量 amp_fwd 和 amp_bwd,否则它们的值将是未定义的,导致计算的结果不正确。
还有一个问题是您在循环中每次都创建了新的 mxArray,但没有及时释放,会导致内存泄漏。您需要在循环结束后释放它们,可以使用 mxDestroyArray 函数。
最后,您需要在每次循环结束后使用 drawnow 函数来更新 MATLAB 图形窗口,否则图形将不会实时显示。
以下是修改后的代码:
#include "engine.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
int main()
{
Engine* ep;
mxArray* t = NULL, * l = NULL, * x = NULL, * y_fwd = NULL, * y_bwd = NULL, * y_res = NULL;
double* t_data, * l_data, * x_data;
double amp_fwd, freq_fwd, wavelen_fwd, amp_bwd, freq_bwd, wavelen_bwd;
int i, j, n;
// 连接到 MATLAB 引擎
if (!(ep = engOpen(NULL)))
{
fprintf(stderr, "无法连接到 MATLAB 引擎\n");
return EXIT_FAILURE;
}
// 创建 t 向量
t = mxCreateDoubleMatrix(1, 1001, mxREAL);
t_data = mxGetPr(t);
for (i = 0; i < 1001; i++)
{
t_data[i] = i * 0.1;
}
// 创建 l 向量
l = mxCreateDoubleScalar(10);
l_data = mxGetPr(l);
// 创建 x 向量
x = mxCreateDoubleMatrix(1, 101, mxREAL);
x_data = mxGetPr(x);
for (i = 0; i < 101; i++)
{
x_data[i] = i * (*l_data) / 200;
}
// 获取用户输入参数
printf("请输入正向波的振幅:\n");
scanf("%lf", &_fwd);
printf("请输入正向波的频率:\n");
scanf("%lf", &freq_fwd);
printf("请输入正向波的波长:\n");
scanf("%lf", &wavelen_fwd);
printf("请输入反向波的振幅:\n");
scanf("%lf", &_bwd);
printf("请输入反向波的频率:\n");
scanf("%lf", &freq_bwd);
printf("请输入反向波的波长:\n");
scanf("%lf", &wavelen_bwd);
// 循环每个时间点,计算波形并绘图
for (n = 0; n < 1001; n++)
{
y_fwd = mxCreateDoubleMatrix(1, 101, mxREAL);
y_bwd = mxCreateDoubleMatrix(1, 101, mxREAL);
y_res = mxCreateDoubleMatrix(1, 101, mxREAL);
for (j = 0; j < 101; j++)
{
*(mxGetPr(y_fwd) + j) = amp_fwd * sin(2 * 3.1416 * (t_data[n] * freq_fwd - x_data[j] / wavelen_fwd));
*(mxGetPr(y_bwd) + j) = amp_bwd * sin(2 * 3.1416 * (t_data[n] * freq_bwd + x_data[j] / wavelen_bwd));
*(mxGetPr(y_res) + j) = *(mxGetPr(y_fwd) + j) + *(mxGetPr(y_bwd) + j);
}
engEvalString(ep, "clf");
engEvalString(ep, "subplot(3,1,1);plot(x,y_fwd,'r');title('正向波');axis([0 10 -2 2]);");
engEvalString(ep, "subplot(3,1,2);plot(x,y_bwd,'b');title('反向波');axis([0 10 -2 2]);");
engEvalString(ep, "subplot(3,1,3);plot(x,y_res,'g');title('合成波形');axis([0 10 -4 4]);");
engEvalString(ep, "drawnow;");
mxDestroyArray(y_fwd);
mxDestroyArray(y_bwd);
mxDestroyArray(y_res);
}
// 释放内存并关闭 MATLAB 引擎
mxDestroyArray(t);
mxDestroyArray(l);
mxDestroyArray(x);
engClose(ep);
return EXIT_SUCCESS;
}
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
根据您提供的信息,我大致看出两个问题:
首先,关于坐标轴闪烁不停的问题,可能是由于代码中的图形更新频率太快导致的。您可以尝试在每次循环中加入一个延时,比如使用Sleep函数,给MATLAB足够的时间来更新图形。例如在每次循环中加入 Sleep(100)
。同时,您也可以尝试在执行完打开引擎的操作后,添加 engEvalString(ep, "uiwait(gcf)");
代码,让程序暂停等待用户界面(MATLAB图形界面)加载完成。
接下来,关于MATLAB图像不出来的问题,根据您提供的代码,我发现在循环每个时间点,计算波形并绘图的部分,代码中只对y_fwd、y_bwd、y_res数组赋值,而没有将这些向量传给MATLAB进行绘图。您可以在每次循环结束后,添加以下代码将向量 y_fwd、y_bwd、y_res 传送到 MATLAB 绘图:
mxArray* pArray[3] = { y_fwd, y_bwd, y_res };
for (int k = 0; k < 3; k++)
{
if (pArray[k] != NULL)
{
char command[256];
sprintf(command, "x%d=x',y%d=y(:,%d)',", k, k, k+1);
engEvalString(ep, command);
engPutVariable(ep, command+1, pArray[k]);
}
}
engEvalString(ep, "clf");
engEvalString(ep, "plot(x0 , y0 , 'r', x1 , y1 , 'b', x2 , y2 , 'g')");
engEvalString(ep, "title('波形合成')");
engEvalString(ep, "xlabel('位置')");
engEvalString(ep, "ylabel('振幅')");
engEvalString(ep, "legend('正向波', '反向波', '驻波')");
engEvalString(ep, "axis([0 10 -5 5])");
其中mxArray* pArray[3] = { y_fwd, y_bwd, y_res }定义了三个向量的数组,通过循环将每个向量传送到MATLAB中,再调用MATLAB的plot函数绘制图像。
同时,如果您使用的是最新版的MATLAB(R2019a及以后版本),可以试试在代码执行前添加以下两行代码,用以禁用MATLAB的硬件加速。这个问题的原因可能是由于硬件加速与VS不兼容所导致的。
engEvalString(ep, "matlab.graphics.Renderer.use('software')");
engEvalString(ep, "set(groot,'DefaultFigureRenderer','painters')");
最终完整代码如下:
#include "engine.h"已黑化的小白 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
int main()
{
Engine* ep;
mxArray* t = NULL, * l = NULL, * x = NULL, * y_fwd = NULL, * y_bwd = NULL, * y_res = NULL;
double* t_data, * l_data, * x_data;
double amp_fwd, freq_fwd, wavelen_fwd, amp_bwd, freq_bwd, wavelen_bwd;
int i, j, n;
// 连接到 MATLAB 引擎
if (!(ep = engOpen(NULL)))
{
fprintf(stderr, "无法连接到 MATLAB 引擎\n");
return EXIT_FAILURE;
}
// 添加禁用硬件加速代码
engEvalString(ep, "matlab.graphics.Renderer.use('software')");
engEvalString(ep, "set(groot,'DefaultFigureRenderer','painters')");
// 创建 t 向量
t = mxCreateDoubleMatrix(1, 1001, mxREAL);
t_data = mxGetPr(t);
for (i = 0; i < 1001; i++)
{
t_data[i] = i * 0.1;
}
// 创建 l 向量
l = mxCreateDoubleScalar(10);
l_data = mxGetPr(l);
// 创建 x 向量
x = mxCreateDoubleMatrix(1, 101, mxREAL);
x_data = mxGetPr(x);
for (i = 0; i < 101; i++)
{
x_data[i] = i * (*l_data) / 200;
}
// 获取用户输入参数
printf("请输入正向波的振幅:\n");
scanf("%lf", &_fwd);
printf("请输入正向波的频率:\n");
scanf("%lf", &freq_fwd);
printf("请输入正向波的波长:\n");
scanf("%lf", &wavelen_fwd);
printf("请输入反向波的振幅:\n");
scanf("%lf", &_bwd);
printf("请输入反向波的频率:\n");
scanf("%lf", &freq_bwd);
printf("请输入反向波的波长:\n");
scanf("%lf", &wavelen_bwd);
// 循环每个时间点,计算波形并绘图
for (n = 0; n < 1001; n++)
{
y_fwd = mxCreateDoubleMatrix(1, 101, mxREAL);
y_bwd = mxCreateDoubleMatrix(1, 101, mxREAL);
y_res = mxCreateDoubleMatrix(1, 101, mxREAL);
for (j = 0; j < 101; j++)
{
*(mxGetPr(y_fwd) + j) = amp_fwd * sin(2 * 3.1416 * (t_data[n] * freq_fwd - x_data[j] / wavelen_fwd));
*(mxGetPr(y_bwd) + j) = amp_bwd * sin(2 * 3.1416 * (t_data[n] * freq_bwd + x_data[j] / wavelen_bwd));
*(mxGetPr(y_res) + j) = *(mxGetPr(y_fwd) + j) + *(mxGetPr(y_bwd) + j);
}
// 将向量传送给 MATLAB 绘制图像
mxArray* pArray[3] = { y_fwd, y_bwd, y_res };
for (int k = 0; k < 3; k++)
{
if (pArray[k] != NULL)
{
char command[256];
sprintf(command, "x%d=x',y%d=y(:,%d)',", k, k, k+1);
engEvalString(ep, command);
engPutVariable(ep, command+1, pArray[k]);
}
}
engEvalString(ep, "clf");
engEvalString(ep, "plot(x0 , y0 , 'r', x1 , y1 , 'b', x2 , y2 , 'g')");
engEvalString(ep, "title('波形合成')");
engEvalString(ep, "xlabel('位置')");
engEvalString(ep, "ylabel('振幅')");
engEvalString(ep, "legend('正向波', '反向波', '驻波')");
engEvalString(ep, "axis([0 10 -5 5])");
// 暂停等待界面加载完成
engEvalString(ep, "uiwait(gcf)");
mxGetPr(y_fwd);
mxGetPr(y_bwd);
mxGetPr(y_res);
mxDestroyArray(y_fwd);
mxDestroyArray(y_bwd);
mxDestroyArray(y_res);
// 添加延时防止刷新过快
Sleep(100);
}
// 关闭 MATLAB 引擎
mxDestroyArray(t);
mxDestroyArray(l);
mxDestroyArray(x);
engClose(ep);
return 0;
}
希望以上解答能够帮到您,如果还有问题欢迎继续提问!
如果我的回答解决了您的问题,请采纳!
#include "engine.h"
#include
#include
#include
#include
int main()
{
Engine* ep;
mxArray* t = NULL, *l = NULL, *x = NULL, *y_fwd = NULL, *y_bwd = NULL, *y_res = NULL;
double* t_data, *l_data, *x_data;
double amp_fwd, freq_fwd, wavelen_fwd, amp_bwd, freq_bwd, wavelen_bwd;
int i, j, n;
// 连接到 MATLAB 引擎
if (!(ep = engOpen(NULL)))
{
fprintf(stderr, "无法连接到 MATLAB 引擎\
");
return EXIT_FAILURE;
}
// 创建 t 向量
t = mxCreateDoubleMatrix(1, 1001, mxREAL);
t_data = mxGetPr(t);
for (i = 0; i < 1001; i++)
{
t_data[i] = i * 0.1;
}
// 创建 l 向量
l = mxCreateDoubleScalar(10);
l_data = mxGetPr(l);
// 创建 x 向量
x = mxCreateDoubleMatrix(1, 101, mxREAL);
x_data = mxGetPr(x);
for (i = 0; i < 101; i++)
{
x_data[i] = i * (*l_data) / 200;
}
// 获取用户输入参数
printf("请输入正向波的振幅:\
");
scanf("%lf", &_fwd);
printf("请输入正向波的频率:\
");
scanf("%lf", &freq_fwd);
printf("请输入正向波的波长:\
");
scanf("%lf", &wavelen_fwd);
printf("请输入反向波的振幅:\
");
scanf("%lf", &_bwd);
printf("请输入反向波的频率:\
");
scanf("%lf", &freq_bwd);
printf("请输入反向波的波长:\
");
scanf("%lf", &wavelen_bwd);
// 循环每个时间点,计算波形并绘图
for (n = 0; n < 1001; n++)
{
y_fwd = mxCreateDoubleMatrix(1, 101, mxREAL);
y_bwd = mxCreateDoubleMatrix(1, 101, mxREAL);
y_res = mxCreateDoubleMatrix(1, 101, mxREAL);
for (j = 0; j < 101; j++)
{
*(mxGetPr(y_fwd) + j) = amp_fwd * sin(2 * 3.1416 * (t_data[n] * freq_fwd - x_data[j] / wavelen_fwd));
*(mxGetPr(y_bwd) + j) = amp_bwd * sin(2 * 3.1416 * (t_data[n] * freq_bwd + x_data[j] / wavelen_bwd));
*(mxGetPr(y_res) + j) = *(mxGetPr(y_fwd) + j) + *(mxGetPr(y_bwd) + j);
}
engEvalString(ep, "clf");
engEvalString(ep, "plot(x , y_fwd , 'r', x , y_bwd , 'b', x , y_res , 'g')");
engEvalString(ep, "title('波形合成')");
engEvalString(ep, "xlabel('位置')");
engEvalString(ep, "ylabel('振幅')");
engEvalString(ep, "legend('正向波', '反向波', '驻波')");
engEvalString(ep, "axis([0 10 -5 5])");
engEvalString(ep, "drawnow");
mxGetPr(y_fwd);
mxGetPr(y_bwd);
mxGetPr(y_res);
mxDestroyArray(y_fwd);
mxDestroyArray(y_bwd);
mxDestroyArray(y_res);
}
// 关闭 MATLAB 引擎
mxDestroyArray(t);
mxDestroyArray(l);
mxDestroyArray(x);
engClose(ep);
return 0;
}