文章目录

  • 一、问题描述
  • 二、算法步骤
  • 三、MATLAB代码

一、问题描述

  给定空间nnn个点,计算最小包围球,使得所有给定点均在球面以内(包括在球面上)。

二、算法步骤

  最小包围球算法可以在最小覆盖圆算法的基础上修改得到:(1)将平面不共线三点确定一个圆的算法改成空间不共线三点确定一个圆的算法(详见博文:空间圆弧路径参数化);(2)增加一个内循环,计算空间不共面四点确定一个球面的算法(详见博文:任意四面体的外接球/三维空间不共面四点确定唯一球面)。

三、MATLAB代码

%{Function: draw_sphere
Description: 画球面
Input: 球心sphereCenter,球半径radius
Output: 无
Author: Marc Pony(marc_pony@163.com)
%}
function draw_sphere(sphereCenter, radius)
[x,y,z] = sphere(200);
x = x * radius + sphereCenter(1);
y = y * radius + sphereCenter(2);
z = z * radius + sphereCenter(3);
h = surf(x, y, z);
xlabel('x')
ylabel('y')
zlabel('z')
set(h, 'FaceAlpha', 0.3, 'MarkerEdgeColor', 'none')
shading interp
end
%{Function: get_circle_center_3D
Description: 求空间三点确定的圆周的圆心
Input: 空间三个点a,b,c
Output: 空间圆周圆心center
Author: Marc Pony(marc_pony@163.com)
%}
function center = get_circle_center_3D(a, b, c)
x1 = a(1);
y1 = a(2);
z1 = a(3);
x2 = b(1);
y2 = b(2);
z2 = b(3);
x3 = c(1);
y3 = c(2);
z3 = c(3);
x4 = 0.5 * (x1 + x2);
y4 = 0.5 * (y1 + y2);
z4 = 0.5 * (z1 + z2);x5 = 0.5 * (x2 + x3);
y5 = 0.5 * (y2 + y3);
z5 = 0.5 * (z2 + z3);a11 = x2 - x1;
a12 = y2 - y1;
a13 = z2 - z1;
b1 = x4 * a11 + y4 * a12 + z4 * a13;a21 = x3 - x2;
a22 = y3 - y2;
a23 = z3 - z2;
b2 = x5 * a21 + y5 * a22 + z5 * a23;a31 = (y1 - y2) * (z2 - z3) - (y2 - y3) * (z1 - z2);
a32 = (x2 - x3) * (z1 - z2) - (x1 - x2) * (z2 - z3);
a33 = (x1 - x2) * (y2 - y3) - (x2 - x3) * (y1 - y2);
b3 = x3 * a31 + y3 * a32 + z3 * a33;center = zeros(3, 1);
temp = a11 * (a22 * a33 - a23 * a32) + a12 * (a23 * a31 - a21 * a33) + a13 * (a21 * a32 - a22 * a31);
center(1) = ((a12 * a23 - a13 * a22) * b3 + (a13 * a32 - a12 * a33) * b2 + (a22 * a33 - a23 * a32) * b1) / temp;
center(2) = -((a11 * a23 - a13 * a21) * b3 + (a13 * a31 - a11 * a33) * b2 + (a21 * a33 - a23 * a31) * b1) / temp;
center(3) = ((a11 * a22 - a12 * a21) * b3 + (a12 * a31 - a11 * a32) * b2 + (a21 * a32 - a22 * a31) * b1) / temp;
end
%{Function: get_distance_square_3D
Description: 求空间两点之间距离的平方
Input: 空间两点a,b
Output: 空间两点之间距离的平方
Author: Marc Pony(marc_pony@163.com)
%}
function distanceSquare = get_distance_square_3D(a, b)
distanceSquare = (a(1) - b(1))^2 + (a(2) - b(2))^2 + (a(3) - b(3))^2;
end
%{Function: get_sign
Description: 求实数x的符号
Input: 实数x
Output: 实数x的符号y
Author: Marc Pony(marc_pony@163.com)
%}
function y = get_sign(x)
if abs(x) < 1.0e-8y = 0;
elseif x < 0.0y = -1;elsey = 1;end
end
end
%{Function: get_sphere_center
Description: 求四面体外接球的球心
Input: 空间不共面四个点A,B,C,D
Output: 球面球心sphereCenter
Author: Marc Pony(marc_pony@163.com)
%}
function sphereCenter = get_sphere_center(A, B, C, D)
x1 = A(1);
y1 = A(2);
z1 = A(3);
x2 = B(1);
y2 = B(2);
z2 = B(3);
x3 = C(1);
y3 = C(2);
z3 = C(3);
x4 = D(1);
y4 = D(2);
z4 = D(3);a11 = x2 - x1;
a12 = y2 - y1;
a13 = z2 - z1;
b1 = 0.5 * ((x2 - x1) * (x2 + x1) + (y2 - y1) * (y2 + y1) + (z2 - z1) * (z2 + z1));a21 = x3 - x1;
a22 = y3 - y1;
a23 = z3 - z1;
b2 = 0.5 * ((x3 - x1) * (x3 + x1) + (y3 - y1) * (y3 + y1) + (z3 - z1) * (z3 + z1));a31 = x4 - x1;
a32 = y4 - y1;
a33 = z4 - z1;
b3 = 0.5 * ((x4 - x1) * (x4 + x1) + (y4 - y1) * (y4 + y1) + (z4 - z1) * (z4 + z1));temp = a11 * (a22 * a33 - a23 * a32) + a12 * (a23 * a31 - a21 * a33) + a13 * (a21 * a32 - a22 * a31);
x0 = ((a12 * a23 - a13 * a22) * b3 + (a13 * a32 - a12 * a33) * b2 + (a22 * a33 - a23 * a32) * b1) / temp;
y0 = -((a11 * a23 - a13 * a21) * b3 + (a13 * a31 - a11 * a33) * b2 + (a21 * a33 - a23 * a31) * b1) / temp;
z0 = ((a11 * a22 - a12 * a21) * b3 + (a12 * a31 - a11 * a32) * b2 + (a21 * a32 - a22 * a31) * b1) / temp;
sphereCenter = [x0; y0; z0];
end
%{Function: min_enclosing_sphere
Description: 求三维空间pointCount个点的最小包围球
Input: 空间pointCount个点的坐标(x,y,z),点个数pointCount
Output: 空间pointCount个点的最小包围球球心sphereCenter,半径radius
Author: Marc Pony(marc_pony@163.com)
%}
function [sphereCenter, radius] = min_enclosing_sphere(x, y, z, pointCount)
p = [x(:)'; y(:)'; z(:)'];
p = p(:, randperm(pointCount)); %随机打乱数据
sphereCenter = p(:, 1);
radiusSquare = 0.0;
for i = 2 : pointCountif get_sign(get_distance_square_3D(p(:, i), sphereCenter) - radiusSquare) > 0sphereCenter = p(:, i);radiusSquare = 0.0;for j = 1 : iif get_sign(get_distance_square_3D(p(:, j), sphereCenter) - radiusSquare) > 0sphereCenter = 0.5 * (p(:, i) + p(:, j));radiusSquare = get_distance_square_3D(p(:, j), sphereCenter);for k = 1 : jif get_sign(get_distance_square_3D(p(:, k), sphereCenter) - radiusSquare) > 0sphereCenter = get_circle_center_3D(p(:, i), p(:, j), p(:, k));radiusSquare = get_distance_square_3D(p(:, i), sphereCenter);for m = 1 : kif get_sign(get_distance_square_3D(p(:, m), sphereCenter) - radiusSquare) > 0sphereCenter = get_sphere_center(p(:, i), p(:, j), p(:, k), p(:, m));radiusSquare = get_distance_square_3D(p(:, i), sphereCenter);endendendendendendend
end
radius = sqrt(radiusSquare);
end
clc
clear
close allfor pointCount = [2, 3, 100, 1000]phi = pi * rand(pointCount, 1);theta = 2 * pi * rand(pointCount, 1);R = 100 * rand(pointCount, 1);x = R .* sin(phi) .* cos(theta);y = R .* sin(phi) .* sin(theta);z = R .* cos(phi);[sphereCenter, radius] = min_enclosing_sphere(x, y, z, pointCount);figure('color', 'w')draw_sphere(sphereCenter, radius)hold onplot3(x, y, z, 'r+')axis equal tightif sum(sqrt((x - sphereCenter(1)).^2 + (y - sphereCenter(2)).^2 + (z - sphereCenter(3)).^2) > radius + 0.0001) > 0disp('至少有一个点在球面以外')end
end

最小包围球(附完整代码)相关推荐

  1. 三次样条拟合(附完整代码)

    文章目录 一.推导步骤 二.三种不同端点约束下的三次样条拟合 1.给定起始速度 v 0 v_0 v0​与结束速度 v n v_n vn​ 2.起始位置 q 0 q_0 q0​与结束位置 q n q_n ...

  2. Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(一)

    Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(一) 本文目录: 一.[旋转的精灵女孩]案例运行效果 二.Three.js简介 三.Three.js代码正常运行显示条件 (1)不载入 ...

  3. 想要快速爬取整站图片?速进(附完整代码)

      大家好,我是不温卜火,是一名计算机学院大数据专业大三的学生,昵称来源于成语-不温不火,本意是希望自己性情温和.作为一名互联网行业的小白,博主写博客一方面是为了记录自己的学习过程,另一方面是总结自己 ...

  4. 【仿真】Carla之收集数据快速教程 (附完整代码)

    收集过程可视化展示,随后进入正文: 参考与前言 看到仿真群对这类任务下(用carla收集数据然后再做训练等) 需求量大,顺手马上写一个好了,首先收集数据需要考虑清楚: 收集什么数据,需要什么样的数据格 ...

  5. Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(三)

    Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(三) 本篇目录: 六.完整构建整个[旋转的精灵女孩]实例 (1).新建.启动webGL工程空间 (2).构建项目的目录层次结构 (2. ...

  6. Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(二)

    Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(二) 本篇目录: 五.实例中所使用的代码语法详细解释 (1).构建一个三维空间场景 (2).选择一个透视投影相机作为观察点 (a).创 ...

  7. php 3d animation,css3D+动画的例子(附完整代码)

    本篇文章给大家带来的内容是关于css3D+动画的例子(附完整代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 前言 最近玩了玩用css来构建3D效果,写了几个demo,所以博客总 ...

  8. Py之pygame:有趣好玩—利用pygame库实现鱼儿自动实时目标跟踪(附完整代码)

    Py之pygame:有趣好玩-利用pygame库实现鱼儿自动实时目标跟踪(附完整代码) 目录 输出结果 实现代码 输出结果 实现代码 #Py之pygame:利用pygame库实现鱼儿自动实时目标跟踪i ...

  9. c++代码好玩_Py之pygame:有趣好玩—利用pygame库实现鱼儿自动实时目标跟踪(附完整代码)...

    Py之pygame:有趣好玩-利用pygame库实现鱼儿自动实时目标跟踪(附完整代码) 目录 输出结果 实现代码 输出结果 ​ 实现代码 #Py之pygame:利用pygame库实现鱼儿自动实时目标跟 ...

最新文章

  1. html语言区别大小写吗,用HTML语言制作静态网页基础问题1.标注是否区分大小写?2.下 爱问知识人...
  2. 在安装完成oracle的时候,需要su - oracle,但有时候出现ulimit pize...
  3. Latex合并及插入图片相关问题
  4. 一小时搞明白自定义注解(Annotation)
  5. apriori算法c++_关联分析——基于Apriori算法实现
  6. matlab矩阵的低秩分解,低秩分解的matlab代码看不懂,分解的两个矩阵在哪呀??...
  7. [jQuery原理] jQueryDOM操作相关方法
  8. 关于《构建之法》阅读笔记 的致歉博客
  9. 《绝地求生》外挂源代码被公布,或迎神仙大战时代?
  10. carplay是否可以用安卓系统,carplay能连接安卓手机吗
  11. c语言编写个人收支管理系统,个人收支管理系统
  12. 怎么在Excel中快速将英文翻译为中文
  13. 李阳疯狂英语学习方法大全集-英语,单词
  14. HMM(Hidden Markov Model)
  15. 1药网母公司路演PPT曝光:发行区间14到16美元 中旬上市
  16. 关于win10系统镜像下载安装问题
  17. 基于Apache Hudi构建智能湖仓实践(附亚马逊工程师代码)
  18. 毕业季基于spring的基于安卓APP的基于ssm框架的基于微信小程序的管理系统设计与开发(开题+源码+讲解+论文)
  19. 北京清华大学英文地址
  20. HDU4466_Triangle

热门文章

  1. 人工智能真的要取代人类了?
  2. 谷歌浏览器Chrome通过命令截图整个网页,screen,通过插件生成gif图片,以及通过插件进行录屏
  3. qt中glMultiTexCoord2fARB报错
  4. 苹果App store 2015最新审核标准
  5. Linux系统部署solr服务,不配置Tomcat服务器
  6. 网络诊断,浏览器不能上网,其他软件都能上网
  7. excel插入图片(利用vba)
  8. 解决Hibernate:could not initialize proxy - no Session
  9. Error response from daemon: conflict: unable to delete 31f279e888c0 (must be forced) - image is bein
  10. ODOO13 开发教程三 开始你的第一个模块