三维空间两直线/线段最短距离、线段计算算法 【转】

https://segmentfault.com/a/1190000006111226

 


d(ls,lt)=|sjtj|=|s0t0+(becd)u⃗ (aebd)v⃗ acb
d(ls,lt)=|sjtj|=|s0t0+(becd)u⃗ (aebd)v⃗ acb2|

 

 

具体实现代码如下(C#实现):

public bool IsEqual(double d1, double d2) { if (Math.Abs(d1 - d2) < 1e-7) return true; return false; } public double SqureDistanceSegmentToSegment(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, double x4, double y4, double z4) { // 解析几何通用解法,可以求出点的位置,判断点是否在线段上 // 算法描述:设两条无限长度直线s、t,起点为s0、t0,方向向量为u、v // 最短直线两点:在s1上为s0+sc*u,在t上的为t0+tc*v // 记向量w为(s0+sc*u)-(t0+tc*v),记向量w0=s0-t0 // 记a=u*u,b=u*v,c=v*v,d=u*w0,e=v*w0——(a); // 由于u*w=、v*w=0,将w=-tc*v+w0+sc*u带入前两式得: // (u*u)*sc - (u*v)*tc = -u*w0 (公式2) // (v*u)*sc - (v*v)*tc = -v*w0 (公式3) // 再将前式(a)带入可得sc=(be-cd)/(ac-b2)、tc=(ae-bd)/(ac-b2)——(b) // 注意到ac-b2=|u|2|v|2-(|u||v|cosq)2=(|u||v|sinq)2不小于0 // 所以可以根据公式(b)判断sc、tc符号和sc、tc与1的关系即可分辨最近点是否在线段内 // 当ac-b2=0时,(公式2)(公式3)独立,表示两条直线平行。可令sc=0单独解出tc // 最终距离d(L1、L2)=|(P0-Q0)+[(be-cd)*u-(ae-bd)v]/(ac-b2)| double ux = x2 - x1; double uy = y2 - y1; double uz = z2 - z1; double vx = x4 - x3; double vy = y4 - y3; double vz = z4 - z3; double wx = x1 - x3; double wy = y1 - y3; double wz = z1 - z3; double a = (ux * ux + uy * uy + uz * uz); //u*u double b = (ux * vx + uy * vy + uz * vz); //u*v double c = (vx * vx + vy * vy + vz * vz); //v*v double d = (ux * wx + uy * wy + uz * wz); //u*w double e = (vx * wx + vy * wy + vz * wz); //v*w double dt = a * c - b * b; double sd = dt; double td = dt; double sn = 0.0;//sn = be-cd double tn = 0.0;//tn = ae-bd if (IsEqual(dt, 0.0)) { //两直线平行 sn = 0.0; //在s上指定取s0 sd = 1.00; //防止计算时除0错误 tn = e; //按(公式3)求tc td = c; } else { sn = (b * e - c * d); tn = (a * e - b * d); if (sn < 0.0) { //最近点在s起点以外,同平行条件 sn = 0.0; tn = e; td = c; } else if (sn > sd) { //最近点在s终点以外(即sc>1,则取sc=1) sn = sd; tn = e + b; //按(公式3)计算 td = c; } } if (tn < 0.0) { //最近点在t起点以外 tn = 0.0; if (-d < 0.0) //按(公式2)计算,如果等号右边小于0,则sc也小于零,取sc=0 sn = 0.0; else if (-d > a) //按(公式2)计算,如果sc大于1,取sc=1 sn = sd; else { sn = -d; sd = a; } } else if (tn > td) { tn = td; if ((-d + b) < 0.0) sn = 0.0; else if ((-d + b) > a) sn = sd; else { sn = (-d + b); sd = a; } } double sc = 0.0; double tc = 0.0; if (IsEqual(sn, 0.0)) sc = 0.0; else sc = sn / sd; if (IsEqual(tn, 0.0)) tc = 0.0; else tc = tn / td; double dx = wx + (sc * ux) - (tc * vx); double dy = wy + (sc * uy) - (tc * vy); double dz = wz + (sc * uz) - (tc * vz); return dx * dx + dy * dy + dz * dz; }

参考文献:http://geomalgorithms.com/a07-_distance.html

  • 2016年07月29日发布

转载于:https://www.cnblogs.com/mazhenyu/p/7154449.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/392093.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【慎思堂】之JS牛腩总结

一 JS基础 1-定义 Javascript是一种脚本语言/描述语言&#xff0c;是一种解释性语言。用于开发交互式web网页&#xff0c;使得网页和用户之间实现了一种实时性的、动态的、交互性的关系&#xff0c;使网页包含更多活跃的元素和更加精彩的内容。 主要用于&#xff1a;表单验证 …

vuejs 轮播_如何在VueJS中设计和构建轮播功能

vuejs 轮播by Fabian Hinsenkamp由Fabian Hinsenkamp设计 A carousel, slideshow, or slider — however you call it this class of UI — has become one of the core elements used in modern web development. Today, it’s almost impossible to find any Website or UI …

iOS绘圆形图-CGContextAddArc各参数说明

2019独角兽企业重金招聘Python工程师标准>>> 1.使用 UIGraphicsGetCurrentContext() 画圆 CGContextAddArc(<#CGContextRef _Nullable c#>, <#CGFloat x#>, <#CGFloat y#>, <#CGFloat radius#>, <#CGFloat startAngle#>, <#CGFlo…

c语言中if和goto的用法,C语言中if和goto的用法.doc

C语言中if和goto的用法C语言中&#xff0c;if是一个条件语句&#xff0c;用法??if(条件表达式) 语句如果满足括号里面表达式&#xff0c;表示逻辑为真于是执行后面的语句&#xff0c;否则不执行(表达式为真则此表达式的值不为0&#xff0c;为假则为0&#xff0c;也就是说&…

数据挖掘—K-Means算法(Java实现)

算法描述 &#xff08;1&#xff09;任意选择k个数据对象作为初始聚类中心 &#xff08;2&#xff09;根据簇中对象的平均值&#xff0c;将每个对象赋给最类似的簇 &#xff08;3&#xff09;更新簇的平均值&#xff0c;即计算每个对象簇中对象的平均值 &#xff08;4&#xf…

自我价值感缺失的表现_不同类型的缺失价值观和应对方法

自我价值感缺失的表现Before handling the missing values, we must know what all possible types of it exists in the data science world. Basically there are 3 types to be found everywhere on the web, but in some of the core research papers there is one more ty…

[收藏转载]C# GDI+ 简单绘图(一)

最近对GDI这个东西接触的比较多&#xff0c;也做了些简单的实例&#xff0c;比如绘图板&#xff0c;仿QQ截图等&#xff0e; 废话不多说了&#xff0c;我们先来认识一下这个GDI&#xff0c;看看它到底长什么样. GDI&#xff1a;Graphics Device Interface Plus也就是图形设备接…

mybaties总结+hibernate总结

一、对原生态jdbc程序中问题总结 1.1 jdbc程序 需求&#xff1a;使用jdbc查询mysql数据库中用户表的记录 statement:向数据库中发送一个sql语句 预编译statement&#xff1a;好处&#xff1a;提高数据库性能。 预编译statement向数据库中发送一个sql语句&#xff0c;数据库编译…

客户旅程_我如何充分利用freeCodeCamp的旅程

客户旅程by Catherine Vassant (aka Codingk8)由凯瑟琳瓦森(Catherine Vassant)(又名Codingk8) 我如何充分利用freeCodeCamp的旅程 (How I made the most out of my freeCodeCamp journey) 我的路线图&#xff1f; ️超越课程范围的reeCodeCamp (My road map ?️ to freeCode…

Python14 函数

函数 面向对象编程&#xff1a; 类----class 面向过程编程&#xff1a;过程---def 函数式编程&#xff1a;函数---def def test(x):描述x 1return x#def是定义函数的关键字#test是函数名称#&#xff08;x&#xff09;是参数#x1是 函数体&#xff0c;是一段逻辑代码#return 定义…

学习sql注入:猜测数据库_面向数据科学家SQL:学习简单方法

学习sql注入:猜测数据库We don’t pick a hammer and look for nails — that would be an unusual way of solving problems. The usual way of doing business is to identify the problem first, then look for appropriate tools.我们不用锤子找钉子&#xff0c;那是解决问…

android 百度地图3.0,android 百度地图3.0

一&#xff1a;为地图设置事件注意新版本中要有一个getMapmMapView.getMap().setOnMapStatusChangeListener(listener);OnMapStatusChangeListener listener newOnMapStatusChangeListener() {/*** 手势操作地图&#xff0c;设置地图状态等操作导致地图状态开始改变。* param s…

(摘录)sockaddr与sockaddr_in,sockaddr_un结构体详细讲解

struct sockaddr { unsigned short sa_family; /* address family, AF_xxx */ char sa_data[14]; /* 14 bytes of protocol address */ }; sa_family是地址家族&#xff0c;一般都是“AF_xxx”的形式。好像通常大多用的是都是AF_INET。 sa_data是14字节协议…

数据挖掘—K-中心点聚类算法(Java实现)

K-中心点聚类算法 &#xff08;1&#xff09;任意选择k个对象作为初始的簇中心点 &#xff08;2&#xff09;指派每个剩余对象给离他最近的中心点所表示的簇 &#xff08;3&#xff09;选择一个未被选择的中心点直到所有的中心点都被选择过 &#xff08;4&#xff09;选择一个…

使用akka构建高并发程序_如何使用Akka Cluster创建简单的应用程序

使用akka构建高并发程序If you read my previous story about Scalachain, you probably noticed that it is far from being a distributed system. It lacks all the features to properly work with other nodes. Add to it that a blockchain composed by a single node is…

pandas之数值计算与统计

数值计算与统计 对于DataFrame来说&#xff0c;求和、最大、最小、平均等统计方法&#xff0c;默认是按列进行统计&#xff0c;即axis 0&#xff0c;如果添加参数axis 1则会按照行进行统计。 如果存在空值&#xff0c;在统计时默认会忽略空值&#xff0c;如果添加参数skipna …

python自动化数据报告_如何:使用Python将实时数据自动化到您的网站

python自动化数据报告This tutorial will be helpful for people who have a website that hosts live data on a cloud service but are unsure how to completely automate the updating of the live data so the website becomes hassle free. For example: I host a websit…

一颗站在技术边缘的土豆

2012年开始上专业课&#xff0c;2013年打了一年游戏&#xff0c;年底专业课忘光了&#xff0c;但是蒙混过关没挂科&#xff0c;2014年7月份毕业&#xff0c;对这个社会充满向往。2014年9月份——方正代理商做网络安全公司。2015年3月份跳槽到一家vmware代理商公司。2016年6月&a…

leetcode 839. 相似字符串组(并查集)

如果交换字符串 X 中的两个不同位置的字母&#xff0c;使得它和字符串 Y 相等&#xff0c;那么称 X 和 Y 两个字符串相似。如果这两个字符串本身是相等的&#xff0c;那它们也是相似的。 例如&#xff0c;“tars” 和 “rats” 是相似的 (交换 0 与 2 的位置)&#xff1b; “r…

android intent参数是上次的结果,【Android】7.0 Intent向下一个活动传递数据、返回数据给上一个活动...

1.0 可以利用Intent吧数据传递给上一个活动&#xff0c;新建一个叫“hellotest01”的项目。新建活动FirstActivity&#xff0c;勾选“Generate Layout File”和“Launcher Activity”。image修改AndroidMainifest.xml中的内容&#xff1a;android:name".FirstActivity&quo…