为了在展示实验成果时动态演示理论球体磁异常随其埋深、磁化倾角的变化规律,我用WPF写了一个小程序来作演示。

MatLab计算磁异常数据

首先是计算理论球体磁异常数据,在Matlab中可以很方便地计算。
为了在展示时能够同时改变磁化倾角(is)、埋深(Deep),计算数据时套了两层循环,外层是is从0到90°,内层是Deep从10到100m,里面计算一条剖面上的Za和Hax磁异常数据。实现代码如下:

function Za=sphere_deeps()
% 测点分布范围
dx=5; % X方向测点间距
nx=81; % X方向测点数
xmin=-200; % X方向起点
x=xmin:dx:(xmin+(nx-1)*dx); % X方向范围 u=4*pi*10^(-7); %磁导率
i=pi/2; %有效磁化倾角is
a=0; %剖面磁方位角
T=50000;%地磁场T=50000nT % 球体参数
R1=10; % 球体半径 m
%D1=30; % 球体埋深 m
v1=4*pi*R1^3;
k=0.2; %磁化率
M1=k*T/u; %磁化强度 A/m
m1=M1*v1; %磁矩 % 球体 理论磁异常主剖面
%(x-0),(y-0)
y=0;
Za=zeros(46,nx);
Hax=zeros(46,nx); fp=fopen('za_all.out','w');
for ii=0:90
i=ii*pi/180;
for j=0:45
D1=10+j*2;
Za0=(u*m1*((2*D1.^2-x.^2-y.^2)*sin(i)-3*D1*x.*cos(i)*cos(a)-3*D1*y.*cos(i)*sin(a)))./(4*pi*(x.^2+y.^2+D1.^2).^(5/2));
for k=1:nx
fprintf(fp,'%g ',Za0(k));
end
fprintf(fp,'\n');
end
end
fclose(fp); fp=fopen('hax_all.out','w');
for ii=0:90
i=ii*pi/180;
for j=0:45
D1=10+j*2;
Hax0=(u*m1*((2*x.^2-y.^2-D1.^2)*cos(i)*cos(a)-3*D1*x.*sin(i)+3*x.*y.*cos(i)*sin(a)))./(4*pi*(x.^2+y.^2+D1.^2).^(5/2));
for k=1:nx
fprintf(fp,'%g ',Hax0(k));
end
fprintf(fp,'\n');
end
end
fclose(fp);

最后是将所有数据都输出至za_all.out以及hax_all.out文件中,其中有91(is从0-90°)*46(Deep从10-100m,间隔2m)行数据,每一行中都有nx(81,测线上的点数)个数据。

C#处理数据文件

首先将之前的za_all.out以及hax_all.out文件复制到WPF项目中,并且对其设置属性为“内容”,并“始终复制”。
将数据读取后分别存储在一个三维数组中,即倾角*深度*测点这样的结构。

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Resources;
using System.Windows;
using System.Windows.Resources; namespace GeoMag_Viewer
{
class Values
{
private int iNum = 91;
private int jNum = 81;
public double[, ,] Za3D
{
get;
private set;
}
public double[, ,] Hax3D
{
get;
private set;
} public Values()
{
StreamResourceInfo za3DInfo = Application.GetContentStream(new Uri("Resources/za_all.out", UriKind.Relative));
var za3DStreamReader = new StreamReader(za3DInfo.Stream);
string content = za3DStreamReader.ReadToEnd();
string[] lines = content.Split(new string[] { " \n" }, StringSplitOptions.None);
Za3D = new Double[91, 46, jNum];
for (int l = 0; l < 91; l++)
{
for (int i = 0; i < 46; i++)
{
int index = l * 46 + i;
string[] words = lines[index].Split(new string[] { " " }, StringSplitOptions.None);
for (int j = 0; j < jNum; j++)
{
Za3D[l, i, j] = Double.Parse(words[j]);
}
}
} StreamResourceInfo hax3DInfo = Application.GetContentStream(new Uri("Resources/hax_all.out", UriKind.Relative));
var hax3DStreamReader = new StreamReader(hax3DInfo.Stream);
content = hax3DStreamReader.ReadToEnd();
lines = content.Split(new string[] { " \n" }, StringSplitOptions.None);
Hax3D = new Double[91, 46, jNum];
for (int l = 0; l < 91; l++)
{
for (int i = 0; i < 46; i++)
{
int index = l * 46 + i;
string[] words = lines[index].Split(new string[] { " " }, StringSplitOptions.None);
for (int j = 0; j < jNum; j++)
{
Hax3D[l, i, j] = Double.Parse(words[j]);
}
}
}
}
}
}

使用OxyPlot组件

为了在WPF中绘制曲线图,通过搜索找到了OxyPlot这个开源库,可以方便地绘制我想要的图形。
创建WPF项目后,打开NUGet程序包管理器,搜索OxyPlot,安装OxyPlot for wpf

Xaml代码如下:

 <Window x:Class="GeoMag_Viewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:oxy="http://oxyplot.org/wpf"
xmlns:local="clr-namespace:GeoMag_Viewer"
Title="GeoMag Viewer" Height="350" Width="525">
<Grid Background="Gray">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<oxy:PlotView Grid.Column="0" Name="MyPlotView">
<oxy:PlotView.Series>
<oxy:LineSeries Name="ZaLine"/>
<oxy:LineSeries Name="HaxLine"/>
</oxy:PlotView.Series>
</oxy:PlotView>
<Image Grid.Column="0"
Name="SphereImage"
Source="Resources/ci.jpg"
HorizontalAlignment="Left"
Margin="150,0,0,0"
Width="150"
Height="150"
/>
<Slider Grid.Column="1" Name="DeepSlider"
Orientation="Vertical"
Margin="5,10,5,10"
ValueChanged="DeepSlider_ValueChanged"
Maximum="45"
Minimum="0"
TickFrequency="1"
TickPlacement="TopLeft"
/>
<TextBlock Grid.Column="2"
Name="DeepText"
FontSize="20"
FontWeight="Bold"
TextWrapping="Wrap"
VerticalAlignment="Center"
/>
</Grid> <Slider Grid.Row="1"
Name="angleSlider"
ValueChanged="angleSlider_ValueChanged"
Margin="10,5,10,5"
Maximum="90"
Minimum="0"
TickFrequency="1"
TickPlacement="TopLeft"/>
<TextBlock Grid.Row="2"
Name="tickText"
FontSize="24"
FontWeight="Bold"
Margin="150,0,150,0"
HorizontalAlignment="Center"/>
</Grid>
</Window>

MainWindow.xaml.cs:

OxyPlot绘制曲线是是将Line.ItemSource设置为List,在这儿使用一个列表的二维数组分别保存Za、Hax异常。数组的第一个下标表示角度,第二个下标表示深度。
当用于控制角度、深度的Slider值变化时,分别调用angleSlider_ValueChangedDeepSlider_ValueChanged来改变所要呈现的曲线,即

ZaLine.ItemsSource = Za3DLists[angleIndex, deepIndex];
HaxLine.ItemsSource = Hax3DLists[angleIndex, deepIndex];

这样,拖动Slider滑块,异常曲线就能跟着动态变化了,达到了演示效果。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using OxyPlot;
using OxyPlot.Series;
using OxyPlot.Wpf;
using Microsoft.Win32; namespace GeoMag_Viewer
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.WindowState = WindowState.Maximized;
Values v = new Values();
MyPlotView.Title = "Za/Hax与磁化倾角的关系Demo";
var valueAxis = new LinearAxis() { Title = "磁异常/nT" };
MyPlotView.Axes.Add(valueAxis);
MyPlotView.LegendFontSize = 20;
ZaLine.Title = "Za异常";
HaxLine.Title = "Hax异常";
tickText.Text = "磁化倾角is=0";
DeepText.Text = "球体埋深"; double[, ,] Za3D = v.Za3D;
double[, ,] Hax3D = v.Hax3D;
int lNum = Za3D.GetLength(0);//角度数
int iNum = Za3D.GetLength(1);//深度数
int jNum = Za3D.GetLength(2);//单测线点数
Za3DLists = new List<DataPoint>[lNum, iNum];
Hax3DLists = new List<DataPoint>[lNum, iNum];
for (int l = 0; l < lNum; l++)
{ for (int i = 0; i < iNum; i++)
{
Za3DLists[l, i] = new List<DataPoint>();
Hax3DLists[l, i] = new List<DataPoint>();
for (int j = 0; j < jNum; j++)
{
int x = -200 + j * 5;
Za3DLists[l, i].Add(new DataPoint(x, Za3D[l, i, j]));
Hax3DLists[l, i].Add(new DataPoint(x, Hax3D[l, i, j]));
}
}
}
angleIndex = 0;
deepIndex = 0;
ZaLine.ItemsSource = Za3DLists[angleIndex, deepIndex];
HaxLine.ItemsSource = Hax3DLists[angleIndex, deepIndex]; width = 100;
height=100;
RotateTransform rt = new RotateTransform(0,width/2,height/2);
SphereImage.RenderTransform = rt; }
double width;
double height;
private void angleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (tickText == null)
{
return;
}
int angle = (int)e.NewValue;
int iAngle = angle;
angleIndex = iAngle;
tickText.Text = "磁化倾角is=" + angle;
ZaLine.ItemsSource = Za3DLists[angleIndex, deepIndex];
HaxLine.ItemsSource = Hax3DLists[angleIndex, deepIndex];
//旋转球体图像
//width / 2, height / 2 使绕图像中心旋转
RotateTransform rt = new RotateTransform(angle, width / 2, height / 2);
SphereImage.RenderTransform = rt;
} private void DeepSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (DeepText == null)
{
return;
}
int iDeep = (int)e.NewValue;
int deep = 10 + 2 * iDeep;
deepIndex = iDeep;
DeepText.Text = "球体埋深\n" + deep+"m";
ZaLine.ItemsSource = Za3DLists[angleIndex, deepIndex];
HaxLine.ItemsSource = Hax3DLists[angleIndex, deepIndex];
} //角度*深度
public List<DataPoint>[,] Za3DLists
{
get;
private set;
} //角度*深度
public List<DataPoint>[,] Hax3DLists
{
get;
private set;
} public int angleIndex
{
get;
private set;
} public int deepIndex
{
get;
private set;
}
}
}

另外,我还在程序中用了一个球体磁场图像,让它随着角度Slider的改变而旋转相应的角度,其实现也很简单,再次不再赘述。

版权声明:本文为博主原创文章,未经博主允许不得转载。

用OxyPlot在WPF中演示正演磁异常的变化规律的更多相关文章

  1. 在WPF中制作正圆形公章

    原文:在WPF中制作正圆形公章 之前,我利用C#与GDI+程序制作过正圆形公章(利用C#制作公章 ,C#制作公章[续])并将它集成到一个小软件中(个性印章及公章的画法及实现),今天我们来探讨一下WPF ...

  2. 使用OxyPlot在WPF中创建图表

    目录(?)[+] Using Nuget 包括OxyPlot在你的应用程序的最简单方法是使用NuGet包管理器在Visual Studio 运行 Visual Studio并开始创建一个新的WPF项目 ...

  3. MVVM模式和在WPF中的实现(二)数据绑定

    MVVM模式解析和在WPF中的实现(二) 数据绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  4. WPF入门教程系列十五——WPF中的数据绑定(一)

    使用Windows Presentation Foundation (WPF) 可以很方便的设计出强大的用户界面,同时 WPF提供了数据绑定功能.WPF的数据绑定跟Winform与ASP.NET中的数 ...

  5. WPF中查看PDF文件

    需要打开PDF文件时,我们第一印象就是使用Adobe Reader.在开发中,经常会遇到需要展示PDF文件的需求.我们会借助于Adobe Reader的Active控件来实现.不过这需要客户的机器上安 ...

  6. WPF中使用ReportViewer报表

    本篇博客将介绍如何在WPF中使用ReportViewer控件. 1. 环境准备:下载安装最新版ReportViewer(PS:需要安装Microsoft SQL Server System CLR T ...

  7. WPF中嵌入普通Win32程序的方法

    公司现在在研发基于.Net中WPF技术的产品,由于要兼容旧有产品,比如一些旧有的Win32程序.第三方的Win32程序等等,还要实现自动登录这些外部Win32程序,因此必须能够将这些程序整合到我们的系 ...

  8. ckrule规则编辑器在wpf中的使用

    当前,ckrule的IDE和业务管理系统都是由winform开发的,规则编辑器也只提供了winform的版本,所以很多的朋友都提出意见,要有wpf的版本.wpf的界面设置和管理都更加的方便. 事实上可 ...

  9. WPF多线程演示

    WPF中的几种处理线程的工作方式: 1.简单的DispatcherTimer类似Timer控件 2.需要处理UI同步时,Dispatcher DispatcherOpertion 3.增强的Threa ...

随机推荐

  1. 枚举基类Enum详解

    本文主要是对枚举类型的基类Enum类做一个介绍: 首先,Enum类位于java.lang包下,根据类的介绍可以发现,Enum类是Java中所有枚举类的父类,将枚举作为一个set或者Map的keys来使 ...

  2. oracle中set define off

    set define off关闭替代变量功能 在SQL*Plus中默认的"&"表示替代变量,也就是说,只要在命令中出现该符号,SQL*Plus就会要你输入替代值.这就意味着 ...

  3. Ecside基于数据库的过滤、分页、排序

    首先ecside展现列表.排序.过滤(该三种操作以下简称为 RSF )的实现原理完全和原版EC一样, 如果您对原版EC的retrieveRowsCallback.sortRowsCallback.fi ...

  4. Gesture(手势)浅析

    1.Gesture的作用 ①在触摸屏上的连续触摸行为,形成某个方向上的移动趋势  (利用手势检测) ②连续画出一个不规则的行为  (利用增加手势) 2.手势检测(GestureDetector) // ...

  5. 编译gcc4.4.6与ICE遇到的几个问题

    1.遇错./.libs/libgcj.so: undefined reference to `__cxa_call_unexpected' 解决:d.错误码:"/.libs/libgcj.s ...

  6. axis2 webservices 411错误解决办法

    错误:org.apache.axis2.AxisFault: Transport error: 411 Error: Length Required 可能会导致这个问题的原因: 1.访问地址经过端口映 ...

  7. logstash indexer和shipper的配置

    [elk@zjtest7-frontend config]$ cat logstash_agent.conf input { file { type => "zj_nginx_acce ...

  8. why constrained regression and Regularized regression equivalent

    problem 1: $\min_{\beta} ~f_\alpha(\beta):=\frac{1}{2}\Vert y-X\beta\Vert^2 +\alpha\Vert \beta\Vert$ ...

  9. 加入商品分类信息,考虑用户所处阶段的 图模型 推荐算法 Rws(random walk with stage)

    场景: 一个新妈妈给刚出生的宝宝买用品,随着宝宝的长大,不同的阶段需要不同的物品. 这个场景中涉及到考虑用户所处阶段,给用户推荐物品的问题. 如果使用用户协同过滤,则需要根据购买记录,找到与用户处于同 ...

  10. ar解压deb包

    解压文件 ar -x libstdc++6_4.7.2-5_i386.deb tar -zxvf data.tar.gz