文章目录
0. 前言
使用MATLAB实现两椭圆重合面积的填充与计算。
1. 准备工作
需要提前掌握的知识如下:
- MATLAB绘制圆、椭圆、矩形等基本平面图形
https://blog.youkuaiyun.com/qq_45384561/article/details/104223407 - 根据椭圆中心坐标、长半轴、偏心率和方向角画椭圆
https://blog.youkuaiyun.com/biubiu_buaa/article/details/71081048?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2defaultBlogCommendFromBaidudefault-1.essearch_pc_relevant&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2defaultBlogCommendFromBaidudefault-1.essearch_pc_relevant - 坐标点的旋转与坐标系的旋转的区别与联系
https://blog.youkuaiyun.com/qq_39800978/article/details/102698993 - 椭圆变换方程(平移+旋转等任意变换)
https://blog.youkuaiyun.com/qq_41685265/article/details/104267256
2. 两同心椭圆重合面积的近似填充
利用椭圆方程求解得到4个交点,逆时针顺序排序后进行填充。
该填充方式为近似填充,即用四边形近似实际重叠面积。
2.1 代码
% Author: Shaw
% Description: 绘制椭圆交叉面积的函数
% Date: 2021/11/18
function testFill_1118(m,n,A1,B1,phi1,A2,B2,phi2)
% m:椭圆原点X
% n:椭圆原点Y
% A1:椭圆1长轴
% B1:椭圆1短轴轴
% phi1:椭圆1绕X轴逆时针旋转角度/°
% A2:椭圆2长轴
% B2:椭圆2短轴
% phi2:椭圆2绕X轴逆时针旋转角度/°
theta = 0:0.001:2*pi;
% 椭圆参数方程
xBhat1 = m + A1 * cos(theta)*cosd(phi1) - B1 * sin(theta) * sind(phi1);
yBhat1 = n + A1 * cos(theta)*sind(phi1) + B1 * sin(theta) * cosd(phi1);
xBhat2 = m + A2 * cos(theta)*cosd(phi2) - B2 * sin(theta) * sind(phi2);
yBhat2 = n + A2 * cos(theta)*sind(phi2) + B2 * sin(theta) * cosd(phi2);
% 绘图
figure
plot(xBhat1, yBhat1,'r')
hold on
plot(xBhat2, yBhat2,'b')
hold on
% 求解交点
syms x y
eq1 = ((x-m)*cosd(phi1) +(y-n)*sind(phi1))^2/A1^2 + (-(x-m)*sind(phi1) +(y-n)*cosd(phi1))^2/B1^2 - 1;
eq2 = ((x-m)*cosd(phi2) +(y-n)*sind(phi2))^2/A2^2 + (-(x-m)*sind(phi2) +(y-n)*cosd(phi2))^2/B2^2 - 1;
[xSolve,ySolve]= solve(eq1,eq2);
% 转符号变量为double数
x0 = double(xSolve);
y0 = double(ySolve);
% 计算交点与椭圆圆心的角度
thetaCom = atan2d(y0-n,x0-m);
array = [x0,y0,thetaCom];
% 依据角度从小到大排列
% fill指令需要坐标逆时针排序
arrayProcess = sortrows(array,3);
% 绘制直线
line(arrayProcess(:,1),arrayProcess(:,2))
hold on
axis equal
% 填充
fill(arrayProcess(:,1),arrayProcess(:,2),'g')
end
close all
clear
clc
% m:椭圆原点X
m = 20;
% N:椭圆原点Y
n = 5;
% A1:椭圆1长轴
A1 = 3;
% B1:椭圆1短轴轴
B1 = 1;
% phi1:椭圆1绕X轴逆时针旋转角度/°
phi1 = 45;
% A2:椭圆2长轴
A2 = 5;
% B2:椭圆2短轴
B2 = 2;
% phi2:椭圆2绕X轴逆时针旋转角度/°
phi2 = 120;
testFill_1118(m,n,A1,B1,phi1,A2,B2,phi2)
2.2 近似填充示意图
椭圆的参数见上述代码,绘制的近似填充示意图如下:
注:
fill函数填充点的坐标顺序必须为逆时针,通过sortrows函数实现各交点与椭圆原点角度的逆时针排序
3. 蒙特卡罗两同心椭圆重合面积的计算及填充
由于近期工作不需要计算重叠面积,所以采用近似的填充方式也可以接受。
如果需要精确计算重叠面积,尤其是不规则图形的重叠面积,则采用蒙特卡罗方法是更好的选择,也能够展现更精确的填充效果!
蒙特卡罗求面积的方法可以理解为:
在比重叠区域面积大的面积为A的区域中随机撒豆子M个,利用重叠面积约束求取所有豆子落在重叠区域上的个数为F,则重叠区域的面积S为
S=A/M*F
“撒豆子”的相关解释可见:
蒙特卡洛算法举例,计算阴影部分面积MATLAB和C语言实现
https://blog.youkuaiyun.com/qq_43530128/article/details/102534301
3.1 代码
% Author: Shaw
% Description: 蒙特卡罗计算椭圆交叉面积,并填充
% Date: 2021/11/20
function area = testMCFill_1120(m,n,A1,B1,phi1,A2,B2,phi2)
% m:椭圆原点X
% n:椭圆原点Y
% A1:椭圆1长轴
% B1:椭圆1短轴轴
% phi1:椭圆1绕X轴逆时针旋转角度/°
% A2:椭圆2长轴
% B2:椭圆2短轴
% phi2:椭圆2绕X轴逆时针旋转角度/°
theta = 0:0.001:2*pi;
% 椭圆参数方程
xBhat1 = m + A1 * cos(theta)*cosd(phi1) - B1 * sin(theta) * sind(phi1);
yBhat1 = n + A1 * cos(theta)*sind(phi1) + B1 * sin(theta) * cosd(phi1);
xBhat2 = m + A2 * cos(theta)*cosd(phi2) - B2 * sin(theta) * sind(phi2);
yBhat2 = n + A2 * cos(theta)*sind(phi2) + B2 * sin(theta) * cosd(phi2);
% 绘图
figure
plot(xBhat1, yBhat1,'r')
hold on
plot(xBhat2, yBhat2,'b')
hold on
% 计算两椭圆长短轴最大值
maxLen = max([A1,B1,A2,B2]);
xmin = m - maxLen;
ymin = n - maxLen;
xmax = m + maxLen;
ymax = n + maxLen;
% 撒豆子个数
N = 10E7;
% 随机豆子
xIn = (xmax - xmin) * rand(1,N) + xmin;
yIn = (ymax - ymin) * rand(1,N) + ymin;
% 椭圆约束
eqIn1 = ((xIn-m).*cosd(phi1) +(yIn-n).*sind(phi1)).^2/A1^2 + (-(xIn-m).*sind(phi1) +(yIn-n).*cosd(phi1)).^2/B1^2 - 1;
eqIn2 = ((xIn-m).*cosd(phi2) +(yIn-n).*sind(phi2)).^2/A2^2 + (-(xIn-m).*sind(phi2) +(yIn-n).*cosd(phi2)).^2/B2^2 - 1;
% 在重叠面积内豆子的下标
index = find(eqIn1<=0 & eqIn2<=0);
% 重叠面积内豆子的个数
count = length(index);
% 重叠面积计算
area = (xmax - xmin) * (ymax - ymin) * count / N;
% 绘制重叠面积
plot(xIn(index), yIn(index), 'g')
hold on
end
close all
clear
clc
% m:椭圆原点X
m = 20;
% N:椭圆原点Y
n = 5;
% A1:椭圆1长轴
A1 = 3;
% B1:椭圆1短轴轴
B1 = 1;
% phi1:椭圆1绕X轴逆时针旋转角度/°
phi1 = 45;
% A2:椭圆2长轴
A2 = 5;
% B2:椭圆2短轴
B2 = 2;
% phi2:椭圆2绕X轴逆时针旋转角度/°
phi2 = 120;
AREA = testMCFill_1120(m,n,A1,B1,phi1,A2,B2,phi2)
3.2 填充示意图
为方便对比,椭圆的参数同上。绘制的填充示意图如下:
3.3 其他博客
- MATLAB求画出的两个椭圆的相交部分的面积
https://sa93g4.smartapps.baidu.com/pages/squestion/squestion?qid=1516340021111183740&rid=2892952722&eid=10889&_swebfr=1&_swebFromHost=vivobrowser
该文给我提供了宝贵的改进思路!
该文利用蒙特卡罗方法计算两椭圆重合面积实现的图如下:
- MATLAB蒙特卡洛(Monte Carlo)方法求椭圆面积
https://blog.youkuaiyun.com/namishizi321/article/details/105945904
该文利用蒙特卡罗方法计算直线和椭圆的交叉面积计算,实现的图如下:
4. 蒙特卡罗两椭圆重合面积的计算及填充
本文虽然只实现了同心椭圆的重合面积的代码,但不同心的情况只需给函数增加俩参数,修改撒豆子的面积和重叠面积约束即可。
此处只给出一张效果图如下:
结语
第50篇,这也是近期我最满意的一篇了
从第1篇到现在,已经过了2年8个月。
专业不对口的日子不好过,路漫漫。
祝妈妈生日快乐~
个人水平有限,有问题欢迎各位大神批评指正!