【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 ...
随机推荐
- TX2 安装 ROS 依赖库错误解决办法
一.更换ubuntu 16.04 更新源 1. 更新源 deb http://mirrors.ustc.edu.cn/ubuntu-ports/ xenial main multiverse rest ...
- Unity3D学习(七):Unity多重采样抗锯齿设置无效的解决办法
前言 学习Shader的过程中发现模型锯齿严重,于是去Edit--Project Settings--Quality选项下将反锯齿设置为了8X Multi Sampling.结果没有任何改变,如图: ...
- PAT1028:List Sorting
1028. List Sorting (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Excel ca ...
- eclipse如何新建项目发布到git
1.首先去查询本地git仓库地址 2.找到项目位置 删除git版本 3.更换git提交目标地址 目标地址是新建的git仓库地址 4.提交
- 你不知道的JavaScript--Item28 垃圾回收机制与内存管理
1.垃圾回收机制-GC Javascript具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存. 原理:垃圾收集器会定期(周期性 ...
- name属性作用+使用$.post()取代name属性在提交表单信息中的作用
name的用途 1)主要是用于获取提交表单的某表单域信息, 作为可与服务器交互数据的HTML元素的服务器端的标示,比如input.select.textarea.框架元素(iframe.frame. ...
- 当Ucenter和应用通信失败
http://blog.sina.com.cn/s/blog_775f158f010135uz.html 失败是常见的. 对于初次接触Ucenter的人来讲,添加一个自己的应用最头疼的就是发现通信失败 ...
- Java 开发, volatile 你必须了解一下
上一篇文章说了 CAS 原理,其中说到了 Atomic* 类,他们实现原子操作的机制就依靠了 volatile 的内存可见性特性.如果还不了解 CAS 和 Atomic*,建议看一下我们说的 CAS ...
- map和flatmap的区别+理解、学习与使用 Java 中的 Optional
转自:map和flatmap的区别 对于stream, 两者的输入都是stream的每一个元素,map的输出对应一个元素,必然是一个元素(null也是要返回),flatmap是0或者多个元素(为n ...
- Python入门:购物车实例
product_list=[('iphone',5800), ('pro',120000), ('python book',120), ('Bike',800), ('coffe',39)] #定义商 ...