我正在研究一种寻找最小/最大非线性函数的进化算法。我有功能齐全的WPF应用程序,但是缺少一个功能: 3D图。
为此,我从免费试用 ilNumerics (提供3D数据可视化)开始。它可以很好地配合文档中的示例使用,但是有些原因使我无法正确绘制自己的3D图形。
所以,这是它目前的行为
这些是非线性函数的图:x1 ^ 4 + x2 ^ 4-0.62 * x1 ^ 2-0.62 * x2 ^ 2
左侧:使用OxyPlot实现的轮廓
右侧:使用ilNumerics实现的3D图形
如您所见,OxyPlot轮廓非常精细,而我尝试使用完全相同的数据绘制的3D图形根本不合适。
我正在尝试使用空间中的点可视化3D表面。 ILNumerics有一个名为 Surface 的类,我必须创建该对象才能绘制图形。它具有以下构造函数:
public Surface(InArray<float> ZXYPositions, InArray<float> C = null, Tuple<float, float> colorsDataRange = null, Colormap colormap = null, object tag = null);
您可以看到ZXYPositions是我实际上遇到的问题。在实例化Surface对象之前,我正在创建一个像这样的数组:
int m = 0;
for (int i = 0; i < p; ++i)
{
for (int j = 0; j < p; ++j)
{
sigma[m, 0] = (float)data[i, j];
sigma[m, 1] = (float)xy[0][i];
sigma[m, 2] = (float)xy[1][j];
m++;
}
}
其中sigma [m,0] = Z; sigma [m,1] = X; sigma [m,2] = Y;
这是问题所在。我在这种方法中找不到任何逻辑错误。 这是负责创建要传递给ilNumerics绘图面板的对象的代码:
var scene = new PlotCube(twoDMode: false) {
// add a surface
new Surface(sigma) {
// make thin transparent wireframes
Wireframe = { Color = Color.FromArgb(50, Color.LightGray) },
// choose a different colormap
Colormap = Colormaps.Jet,
}
};
另外,我想说的是sigma数组构造正确,因为我已经打印出了它的值并且它们绝对正确。
最后,我需要补充一点,当我不创建表面对象并仅绘制数据点时,它看起来更加合理:
但是可悲的是,这不是我想要的。我想用此数据创建一个表面。
答案 0 :(得分:0)
我找到了答案。奇怪的是,一切都很好。.我误解了一件事。当我将ZXYPositions参数传递到曲面时,实际上可以期望只有Z数据可以正确绘制图形。
两个首先的for循环现在看起来像这样:
sigma = data;
如您所见,它们不再循环,因为sigma现在仅包含“解决方案”坐标(即Z坐标),因此我只需要将数据数组分配给sigma。
第二部分,我在其中创建Surface,现在看起来像这样:
var B = ILMath.tosingle(sigma);
var scene = new PlotCube(twoDMode: false) {
// add a surface
new Surface(B) {
// make thin transparent wireframes
Wireframe = { Color = Color.FromArgb(50, Color.LightGray) },
// choose a different colormap
Colormap = Colormaps.Jet,
}
};
scene.Axes.XAxis.Max = (float)arguments[0].Maximum;
scene.Axes.XAxis.Min = (float)arguments[0].Minimum;
scene.Axes.YAxis.Max = (float)arguments[1].Maximum;
scene.Axes.YAxis.Min = (float)arguments[1].Minimum;
scene.First<PlotCube>().Rotation = Matrix4.Rotation(new Vector3(1f, 0.23f, 1), 0.7f);
基本上发生了变化的一件事是将XY轴缩放为适当的值。
这是您的最终结果: