【Matlab&Mathematica】对三维空间上的点进行椭圆拟合
问题是这样:比如有一个地心惯性系的轨道,然后从轨道上取了几个点,问能不能根据这几个点把轨道还原了?
当然,如果知道轨道这几个点的速度的情况下,根据轨道六根数也是能计算轨道的,不过真近点角是随时间变动的。
下面我会用数学的方法来解这个问题,基本思想是通过拟合空间上点的平面与椭球平面的交线将该轨道计算出来,算是一种思路吧。
首先需要有轨道数据,我们就从STK上获得,我使用默认参数生成了一个轨道,如下图:

输出j2000下的位置速度:

取其中5个点进行拟合:

可以先计算椭球,设椭球方程为x^2/a+y^2/b+z^2/c+d=0,然后求其最小二乘函数f(a,b,c,d) = sum((x^2/a+y^2/b+z^2/c+d)^2)。
通过单纯性法求该函数符合上面5个点的最小值时的a,b,c,d四个参数。
matlab里就是用fminsearch函数就行了。
代码如下:
clear all;
close all;
clc; x=[4272.199656,8091.936548,9250.537919,7326.513290,4775.406342];
y=[-9122.847094,-8215.105235,-4377.145579,3801.632308,7889.177050];
z=[332.461913,8019.448934,13254.361230,16413.922920,15098.049929]; fun=@(t)sum((x.^2/t(1)+y.^2/t(2)+z.^2/t(3)+t(4)).^2); [t fval]= fminsearch( fun , rand(4,1)) ; %单纯形法多元优化 t
这里的t就是要求的a,b,c,d四个参数。
我求的参数是
11831.9652077381
7748.53668377191
37674.4028071175
-14504.0838741735
得到椭球方程为:
x^2/11831.96520773810 + y^2/7748.536683771910 + z^2/37674.40280711745 - 14504.08387417353 = 0
Mathematica中画出来就是:
ContourPlot3D[
x^2/11831.96520773810 + y^2/7748.536683771910 +
z^2/37674.40280711745 - 14504.08387417353 == 0, {x, -20000,
20000}, {y, -20000, 20000}, {z, -30000, 30000}]

椭球有了,下面我们求平面,使用ransac进行平面拟合。
我参考了这篇博客:https://blog.csdn.net/u010128736/article/details/53422070
不过他好像也参考了我过去写的ransac直线拟合:https://www.cnblogs.com/tiandsp/archive/2013/06/03/3115743.html,有趣 : )
代码如下:
clc;clear all;close all; iter = 1000; x=[4272.199656,8091.936548,9250.537919,7326.513290,4775.406342];
y=[-9122.847094,-8215.105235,-4377.145579,3801.632308,7889.177050];
z=[332.461913,8019.448934,13254.361230,16413.922920,15098.049929]; data=[x;y;z]; %%% 绘制数据点
figure;plot3(data(1,:),data(2,:),data(3,:),'o');hold on; % 显示数据点
number = size(data,2); % 总点数
bestParameter1=0; bestParameter2=0; bestParameter3=0; % 最佳匹配的参数
sigma = 1;
pretotal=0; %符合拟合模型的数据的个数 for i=1:iter
%%% 随机选择三个点
idx = randperm(number,3);
sample = data(:,idx); %%%拟合直线方程 z=ax+by+c
plane = zeros(1,3);
x = sample(1, :);
y = sample(2, :);
z = sample(3, :); a = ((z(1)-z(2))*(y(1)-y(3)) - (z(1)-z(3))*(y(1)-y(2)))/((x(1)-x(2))*(y(1)-y(3)) - (x(1)-x(3))*(y(1)-y(2)));
b = ((z(1) - z(3)) - a * (x(1) - x(3)))/(y(1)-y(3));
c = z(1) - a * x(1) - b * y(1);
plane = [a b -1 c] mask=abs(plane*[data; ones(1,size(data,2))]); %求每个数据到拟合平面的距离
total=sum(mask<sigma); %计算数据距离平面小于一定阈值的数据的个数 if total>pretotal %找到符合拟合平面数据最多的拟合平面
pretotal=total;
bestplane=plane; %找到最好的拟合平面
end
end
%显示符合最佳拟合的数据
mask=abs(bestplane*[data; ones(1,size(data,2))])<sigma;
hold on;
k = 1;
for i=1:length(mask)
if mask(i)
inliers(1,k) = data(1,i);
inliers(2,k) = data(2,i);
plot3(data(1,i),data(2,i),data(3,i),'r+');
k = k+1;
end
end %%% 绘制最佳匹配平面
bestParameter1 = bestplane(1);
bestParameter2 = bestplane(2);
bestParameter3 = bestplane(4);
xAxis = min(inliers(1,:)):max(inliers(1,:));
yAxis = min(inliers(2,:)):max(inliers(2,:));
[x,y] = meshgrid(-30000:1000:30000);
z = bestParameter1 * x + bestParameter2 * y + bestParameter3;
mesh(x, y, z);
title(['bestPlane: z = ',num2str(bestParameter1),'x + ',num2str(bestParameter2),'y + ',num2str(bestParameter3)]);
拟合结果如下:

然后我们在Mathematica上画出平面与椭球:
代码如下:
data = {{4272.199656, -9122.847094,
332.461913}, {8091.936548, -8215.105235,
8019.448934}, {9250.537919, -4377.145579,
13254.361230}, {7326.513290, 3801.632308, 16413.922920},
{4775.406342, 7889.177050 , 15098.049929}};
P3 = ListPlot3D[data, ColorFunction -> Function[{x, y, z}, Hue[x]]]
P2 = ContourPlot3D[
1.8204 x + 0.81444 y - z - 20.3705 == 0, {x, -30000,
30000}, {y, -30000, 30000}, {z, -30000, 30000}]
P1 = ContourPlot3D[
x^2/11831.96520773810 + y^2/7748.536683771910 +
z^2/37674.40280711745 - 14504.08387417353 == 0, {x, -20000,
20000}, {y, -20000, 20000}, {z, -30000, 30000}]
Show[{P1, P2, P3}]
结果如下:

感觉有那么点意思了。
下面我们求出两个面相交的参数方程,使用Mathematica计算还是比较方便的。
列出以下三个方程:
1.8204 x + 0.81444 y - z - 20.3705 = 0
x^2/11831.96520773810 + y^2/7748.536683771910 + z^2/37674.40280711745 - 14504.08387417353 = 0
z = 23375.89994468299 Sin[t]
这里23375.89994468299 通过sqrt(14504.08387417353*37674.40280711745)求出来的,z是在这个范围内变动的。
使用Mathematica解算如下:
Solve[{1.8204 x + 0.81444 y - z - 20.3705 == 0,
x^2/11831.96520773810 + y^2/7748.536683771910 +
z^2/37674.40280711745 - 14504.08387417353 == 0,
z == 23375.89994468299 Sin[t]}, {x, y, z}]
结果:
{{x -> 2.5336*10^-43 (3.90483*10^43 + 4.48093*10^46 Sin[t] - 7.40177*10^18 Sqrt[
5.65524*10^54 - 8.37291*10^51 Sin[t] - 1.04594*10^55 Sin[t]^2]),
y -> 1.2668*10^-42 (2.28816*10^42 + 2.62575*10^45 Sin[t] + 3.30882*10^18 Sqrt[
5.65524*10^54 - 8.37291*10^51 Sin[t] - 1.04594*10^55 Sin[t]^2]),
z -> 23375.9 Sin[t]},
{x -> 2.5336*10^-43 (3.90483*10^43 + 4.48093*10^46 Sin[t] + 7.40177*10^18 Sqrt[
5.65524*10^54 - 8.37291*10^51 Sin[t] - 1.04594*10^55 Sin[t]^2]),
y -> 1.2668*10^-42 (2.28816*10^42 + 2.62575*10^45 Sin[t] - 3.30882*10^18 Sqrt[
5.65524*10^54 - 8.37291*10^51 Sin[t] - 1.04594*10^55 Sin[t]^2]),
z -> 23375.9 Sin[t]}}
求到这里,这个参数方程已经求出来的,下面我画出来验证一下。
matlab代码如下:
clear all;
close all;
clc; xx=[];yy=[];zz=[]; for t=0:0.001:2*pi
x=2.5336*10^(-43) *(3.90483*10^43 + 4.48093*10^46*sin(t) - 7.40177*10^18*sqrt(5.65524*10^54 - 8.37291*10^51* sin(t) - 1.04594*10^55*sin(t).^2));
y=1.2668*10^(-42) *(2.28816*10^42 + 2.62575*10^45*sin(t) + 3.30882*10^18*sqrt(5.65524*10^54 - 8.37291*10^51 *sin(t) - 1.04594*10^55* sin(t).^2));
z=23375.9* sin(t); if(sqrt(5.65524*10^54 - 8.37291*10^51 *sin(t) - 1.04594*10^55* sin(t).^2)>0)
xx=[xx x];
yy=[yy y];
zz=[zz z];
end
end for t=0:0.001:2*pi
x=2.5336*10^(-43) *(3.90483*10^43 + 4.48093*10^46*sin(t) + 7.40177*10^18*sqrt(5.65524*10^54 - 8.37291*10^51* sin(t) - 1.04594*10^55*sin(t).^2));
y=1.2668*10^(-42) *(2.28816*10^42 + 2.62575*10^45*sin(t) - 3.30882*10^18*sqrt(5.65524*10^54 - 8.37291*10^51 *sin(t) - 1.04594*10^55* sin(t).^2));
z=23375.9* sin(t);
if(sqrt(5.65524*10^54 - 8.37291*10^51 *sin(t) - 1.04594*10^55* sin(t).^2)>0)
xx=[xx x];
yy=[yy y];
zz=[zz z];
end
end plot3(xx,yy,zz,'.') x=[4272.199656,8091.936548,9250.537919,7326.513290,4775.406342];
y=[-9122.847094,-8215.105235,-4377.145579,3801.632308,7889.177050];
z=[332.461913,8019.448934,13254.361230,16413.922920,15098.049929];
hold on
plot3(x,y,z,'ro')
结果如下:

可以看出,点基本都在椭圆周围,效果不错,下面多用几组原始点对比看看:

呵呵,这就比较尴尬了,好像不怎么一样哦。
毕竟,这里只用了5个点,拟合点数多一些效果应该会好些吧 : )
关注公众号: MATLAB基于模型的设计 (ID:xaxymaker) ,每天推送MATLAB学习最常见的问题,每天进步一点点,业精于勤荒于嬉。
打开微信扫一扫哦!
【Matlab&Mathematica】对三维空间上的点进行椭圆拟合的更多相关文章
- Matlab中插值函数汇总(上)
Matlab中插值函数汇总分上下两个部分,主要整合自matlabsky论坛dynamic发表于2009-2-21 21:53:26 的主题帖,以及豆丁网rickoon上传的教材第8章<插值,拟合 ...
- matlab的特殊字符(上下标和希腊字母等)
'T=25\circC',(摄氏度) 下标用 _(下划线) 上标用^ (尖号) 希腊字母等特殊字符用 α \alpha β \beta γ \gamma θ \theta Θ \Theta Г \Ga ...
- C# + Matlab 实现计件工时基于三层BP神经网络的拟合--真实项目
工序工时由该工序的工艺参数决定,有了工时后乘以固定因子就是计件工资.一般参考本地小时工资以及同类小时工资并考虑作业的风险等因素给出固定因子 采用的VS2010 , Matlab2015a 64, 开 ...
- opencv——pcb上寻找mark点(拟合椭圆的方法)
#include "stdafx.h" // FitCircle.cpp : 定义控制台应用程序的入口 #include "cv.h" #include &qu ...
- 史上最全的Matlab资源电子书教程和视频下载合集【超级推荐】
收藏吧,网上搜集的,费了老大劲了,推荐给有需要的人,^_^. MATLAB课件2007北京交通大学.zip 4.87 MB A Guide to MATLAB for Beginners an ...
- Mathematica 和 MATLAB、Maple 并称为三大数学软件
Mathematica是一款科学计算软件,很好地结合了数值和符号计算引擎.图形系统.编程语言.文本系统.和与其他应用程序的高级连接.很多功能在相应领域内处于世界领先地位,它也是使用最广泛的数学软件之一 ...
- 基于 Mathematica 的机器人仿真环境(机械臂篇)[转]
完美的教程,没有之一,收藏学习. 目的 本文手把手教你在 Mathematica 软件中搭建机器人的仿真环境,具体包括以下内容(所使用的版本是 Mathematica 11.1,更早的版本可能缺少某些 ...
- Matlab绘图高级部分
图形是呈现数据的一种直观方式,在用Matlab进行数据处理和计算后,我们一般都会以图形的形式将结果呈现出来.尤其在论文的撰写中,优雅的图形无疑会为文章加分.本篇文章非完全原创,我的工作就是把见到的Ma ...
- (转载)MatLab绘图
转载自:http://www.cnblogs.com/hxsyl/archive/2012/10/10/2718380.html 转载自:http://www.cnblogs.com/jeromebl ...
随机推荐
- Net Core动态加载webservice/WCF
1.动态加载的目的 前端时间和顺丰对接了个项目(PS:顺丰的开发对外能力真的是掉粉),用的webservice 测试时用的无固定IP访问,正式版需要固定IP访问,我的理解是web服务都是全网络可以访问 ...
- Java历程-初学篇 Day01初识java
HelloWorld!!!!! 一,第一个java程序的构成 1,外层框架 class 后面的类名必须与文件名相同 起名方法:1)构成只能有_ $ 字母 数字 2)数字不能开头 3)首字母必须大写 4 ...
- opencv利用hough概率变换拟合得到直线后,利用DDA算法得到直线上的像素点坐标
图片霍夫变换拟合得到直线后,怎样获得直线上的像素点坐标? 这是我今天在图像处理学习中遇到的问题,霍夫变换采用的概率霍夫变换,所以拟合得到的直线信息其实是直线的两个端点的坐标,这样一个比较直接的思路就是 ...
- CAPTCHA---验证码 ---Security code
BotDetect Java CAPTCHA Generator 3. Add BotDetect Java CAPTCHA Library Dependency Here is how to add ...
- C# 读取XML节点属性值
xml文件格式如下: <?xml version="1.0" encoding="UTF-8" ?> <Product type=" ...
- bash: jar: 未找到命令..(command not found)
/bin/bash: jar: command not found 解决办法: cd /usr/bin 必须先进入/usr/bin,下同 sudo ln -s -f /usr/lib/jvm/jdk1 ...
- IntelliJ IDEA(十) :常用操作
IDEA功能详细,快捷键繁多,但是实际开发时不是所有都能用上,如果我们熟悉一些常用的也足够满足我们日常开发了,多的也只是提高我们的B格. 1.自定义主题 IDEA默认的主题有三款,分别是Intelli ...
- java 自定义的注解有什么作用
转自https://zhidao.baidu.com/question/1668622526729638507.html 自定义注解,可以应用到反射中,比如自己写个小框架. 如实现实体类某些属性不自动 ...
- Asp.Net WebAPI中Filter过滤器的使用以及执行顺序
转发自:http://www.cnblogs.com/UliiAn/p/5402146.html 在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行 ...
- orcl数据库命令行怎么导入dmp格式的文件
2018-05-23 1.创建空间 以system的身份登陆orcl 打开SQL Window界面,输入以下命令create tablespace SGXC(表空间的名字)datafile 'D:/S ...