如何用ilNumerics中的ZXYPositions正确绘制3D表面?

时间:2019-05-08 00:37:22

标签: c# wpf math ilnumerics

我想实现什么?

我正在研究一种寻找最小/最大非线性函数的进化算法。我有功能齐全的WPF应用程序,但是缺少一个功能: 3D图

出什么问题了?

为此,我从免费试用 ilNumerics (提供3D数据可视化)开始。它可以很好地配合文档中的示例使用,但是有些原因使我无法正确绘制自己的3D图形。

可视化问题:

所以,这是它目前的行为

error

这些是非线性函数的图: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数组构造正确,因为我已经打印出了它的值并且它们绝对正确。

仅绘制数据点。

最后,我需要补充一点,当我不创建表面对象并仅绘制数据点时,它看起来更加合理:

correct

但是可悲的是,这不是我想要的。我想用此数据创建一个表面

1 个答案:

答案 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轴缩放为适当的值。

最终结果

这是您的最终结果: heart