求解三维空间中两线段之间的最小距离,并求出最小距离对应的两个点

原理解析几何通用解法
    在空间中两条线上最短距离处的点连垂直于两条线L1、L2
    算法描述:设两条无限长度直线s、t,起点为s0、t0,方向向量为u、v
    1、最短直线两点:在s上为s0 + sc*u,在t上的为t0 + tc*v
    2、记向量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);
        w向量与两线段分别垂直时最短,所存在 u*w = 0,v*w = 0   公式(b); 
        由于u*w = 0、v*w = 0,将w = -tc*v + w0 + sc*u 带入公式(b)得:
        (u*u)*sc - (u*v)*tc = -u*w0  (公式2)
        (v*u)*sc - (v*v)*tc = -v*w0  (公式3)
    3、再将前式(a)带入可得sc=(be-cd)/(ac-b²)、tc=(ae-bd)/(ac-b²)  公式(c)
        注意到ac-b2=|u|²|v|²-(|u||v|cosQ)²=(|u||v|sinQ)²不小于0
        所以可以根据公式(c)判断sc、tc符号和sc、tc与1的关系即可分辨最近点是否在线段内
    4、当ac-b2=0时,(公式2)(公式3)独立,表示两条直线平行。可令sc=0单独解出tc
    5、最短距离最终就是w向量的模长

function CalcuateDistance()  {/**计算空间两条直线之间的最短距离 */getShortDistance (firstLineData:any, secondLineData:any) {/**第一条线段对应起终点的坐标 */var x1 = firstLineData.startX;var y1 = firstLineData.startY;var z1 = firstLineData.startZ;var x2 = firstLineData.endX;var y2 = firstLineData.endY;var z2 = firstLineData.endZ;/**第二条线段对应起终点的坐标*/var x3 = secondLineData.startX;var y3 = secondLineData.startY;var z3 = secondLineData.startZ;var x4 = secondLineData.endX;var y4 = secondLineData.endY;var z4 = secondLineData.endZ;var ux = x2 - x1;var uy = y2 - y1;var uz = z2 - z1;var vx = x4 - x3;var vy = y4 - y3;var vz = z4 - z3;var wx = x1 - x3;var wy = y1 - y3;var wz = z1 - z3;/**根据公式(a)计算出对应的数值 */var a = (ux * ux + uy * uy + uz * uz);  //u*uvar b = (ux * vx + uy * vy + uz * vz);  //u*vvar c = (vx * vx + vy * vy + vz * vz);  //v*vvar d = (ux * wx + uy * wy + uz * wz);  //u*w var e = (vx * wx + vy * wy + vz * wz);  //v*wvar dt = a * c - b * b;var sd = dt;var td = dt;/**sn = be - cd */var sn = 0.0;/**tn = ae - bd */var tn = 0.0;if (CalcuateDistance.IsEqual(dt, 0.0)) {/**若dt为0,这说明两条线重合或者平行(三角函数的相关知识) */sn = 0.0;      //在s上指定取s0sd = 1.00;     //防止计算时除0错误tn = Math.E;    //按(公式3)求tctd = c;} else {sn = (b * e - c * d);tn = (a * e - b * d);if (sn < 0.0) {sn = 0.0;tn = e;td = c;} else if (sn > sd) {//最近点在s终点以外(即sc>1,则取sc=1)sn = sd;tn = Math.E + b; //按(公式3)计算td = c;}};if (tn < 0.0) {//最近点在t起点以外tn = 0.0;if (-d < 0.0)    //按(公式2)计算,如果等号右边小于0,则sc也小于零,取sc=0sn = 0.0;else if (-d > a) //按(公式2)计算,如果sc大于1,取sc=1sn = 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;}};var sc = 0.0;var tc = 0.0;if (CalcuateDistance.IsEqual(sn, 0.0))sc = 0.0;elsesc = sn / sd;if (CalcuateDistance.IsEqual(tn, 0.0))tc = 0.0;elsetc = tn / td;/**最终计算W向量的模长,即为空间两条线段的最短距离 */var dx = wx + (sc * ux) - (tc * vx);var dy = wy + (sc * uy) - (tc * vy);var dz = wz + (sc * uz) - (tc * vz);var MinDis = Math.sqrt(dx * dx + dy * dy + dz * dz);var distance = MinDis.toFixed(3);/**两条管线相聚最近上面的点坐标 */let minPoint1X = x1 +  (sc * ux);let minPoint1Y = y1 +  (sc * uy);let minPoint1Z = z1 +  (sc * uz);let minPoint2X = x3 +  (tc * vx);let minPoint2Y  = y3 + (tc * vy);let minPoint2Z  = z3 + (tc * vz);let obj = {distance:distance,point1:{x:minPoint1X,y:minPoint1Y,z:Number(minPoint1Z.toFixed(3))},point2:{x:minPoint2X,y:minPoint2Y,z:Number(minPoint2Z.toFixed(3))},}return obj;},/*** @description 判断是否相等* @param d1 * @param d2 * @returns */IsEqual(d1:number, d2:number):boolean {if (Math.abs(d1 - d2) < Math.pow(10, -7)) {return true;} else {return false;}}
}

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

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

相关文章

国务院办公厅发布:政府类网站网页设计规范(试行)

国务院办公厅于2019年12月发布了《政府类网站网页设计规范&#xff08;试行&#xff09;》。该规范的发布旨在统一政府类网站的设计风格和标准&#xff0c;提升政府网站的用户体验和可访问性&#xff0c;推动政府信息公开和服务的提升。 该规范涵盖了政府类网站的各个方面&…

C语言——编程世界的璀璨明珠

在编程世界中&#xff0c;C语言犹如一颗璀璨的明珠&#xff0c;以其独特的魅力和强大的功能赢得了全球开发者的青睐。自诞生以来&#xff0c;C语言在计算机科学领域一直占据着举足轻重的地位&#xff0c;被誉为编程语言的奠基者之一。本文将从多个方面详细介绍C语言的卓越之处&…

使用Qt自带windeployqt打包QML的exe

1.在开始菜单输入CMD找到对应的Qt开发版本&#xff0c;我的是Qt5.15.2(MinGW 8.1.0 64-bit)。 2.在控制台输入如下字符串&#xff0c;格式为 windeployqt exe绝对路径 --qmldir 工程的绝对路径 如下是我的打包代码。 我需要打包的exe的绝对路径 D:\Prj\Code\Demo\QML\Ana…

【代码学习】Mediapipe人脸检测使用记录

Mediapipe&#xff0c;每秒200-300帧的实时人脸检测&#xff0c;提取画面中的人脸框&#xff0c;实现后续各种应用&#xff1a;人脸属性识别、表情识别、关键点检测、三维重建、增强现实、AI换妆等 code&#xff1a;google/mediapipe: Cross-platform, customizable ML soluti…

C++中,#define和const有什么区别? / 静态链接和动态链接有什么区别?

一、C中&#xff0c;#define和const有什么区别&#xff1f; C中&#xff0c;#define和const都用于定义常量&#xff0c;但它们在用法和特性上存在显著的区别。 定义与用途&#xff1a; #define是C预处理器的指令&#xff0c;用于定义宏。宏可以是函数、对象、类型等&#xf…

国内区块链公司哪个好

目录 1. 蚂蚁金服(Ant Financial) 2. 腾讯(Tencent) 3. 阿里巴巴(Alibaba) 4. 海尔智家(Haier Smart Home

Java异常类型及异常处理方式

本章学习内容&#xff1a;使用异常处理机制&#xff0c;对程序运行过程中出现的异常情况进行捕捉并处理. 目录 &#x1f4cc; Java异常概述 &#x1f4cc; Java异常体系结构 &#x1f4cc; 常见的异常 &#x1f4cc; 异常处理 &#x1f4cc; Java异常概述 ○ 异常的概念&…

【力扣】55.跳跃游戏、45.跳跃游戏Ⅱ

55.跳跃游戏 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&a…

数据库管理-第163期 19c重建ADG的两个方法(20240323

数据库管理163期 2024-03-23 数据库管理-第163期 19c重建ADG的两个方法&#xff08;20240323&#xff09;1 ORA-081032 新办法1 关闭MRP2 恢复备库3 其他操作4 启动备库5 启动MRP 3 老办法4 预告总结 数据库管理-第163期 19c重建ADG的两个方法&#xff08;20240323&#xff09;…

vscode配置c/c++调试环境

本文记录win平台使用vscode远程连接ubuntu server服务器下&#xff0c;如何配置c/c调试环境。 过程 1. 服务器配置编译环境 这里的前置条件是vscode已经能够连接到服务器&#xff0c;第一步安装编译构建套件&#xff08;gcc、g、make、链接器等&#xff09;和调试器&#xf…

vue3之生命周期

Vue3之生命周期 主要Vue生命周期事件被分为两个钩子&#xff0c;分别在事件之前和之后调用&#xff0c;vue应用程序中有4个主要事件(8个钩子)&#xff1a; 创建 ---- 在组建创建时执行挂载 ---- DOM被挂载时执行更新 ---- 当响应数据被修改时执行销毁 ---- 在元素被销毁之前立…

深度学习模型部署(十一)TensorRT写Plugin

什么是plugin & 有什么用&#xff1f; TensorRT的一种机制&#xff0c;以.so的形式插入到网络中实现某些算子。 作用&#xff1a; 实现TensorRT不支持的层替换性能不好的层手动进行图优化算子融合 写Plugin就是自己写算子的CUDA kernel实现。 Plugin与其他layer之间无法…

【数据结构】顺序表和链表详解顺序表和链表的实现

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;数据结构_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.线性表 1.1 顺序表 1.1.1 概念及结构 1.1.2 静态顺序表 1.1.3 动态顺序表 1.2 链表 1.2.1 链表的概念及结构 1.2.2 链表…

馆室一体化查档平台制度有哪些

馆室一体化查档平台制度是指图书馆或档案馆在数字化和信息化的背景下&#xff0c;建立起的集查阅、借阅、咨询、文献传递等多项功能于一体的平台制度。下面是一些常见的馆室一体化查档平台制度&#xff1a; 1. 馆藏管理制度&#xff1a;包括图书和档案的采购、编目、分类、整理…

详解rtklib中main函数如何配置文件(下)

目录 一、main函数流程总结 二、分析识别 -k 后如何配置 三、最后传参的数据文件处理方式 一、main函数流程总结 详解rtklib中main函数如何配置文件&#xff08;上&#xff09;-CSDN博客 在这片文章中讲解了rtklib中main函数的整个流程。 &#xff08;1&#xff09;通过…

最长上升子序列

一、题目描述 B3637 最长上升子序列 二、问题简析 2.1 法一&#xff1a; O ( N 2 ) O(N^2) O(N2) 令 d p [ i ] dp[i] dp[i] 以 a i a_i ai​ 结尾的上升子序列的最大长度。 以 a i a_i ai​ 结尾的上升子序列有两种可能&#xff1a; 1、仅有 a i a_i ai​ 一个元素2…

保研复习概率论2

1.什么是随机变量的数学期望&#xff08;expected value&#xff09;&#xff1f; 如果X是离散型随机变量&#xff0c;其分布列为piP{Xxi}(i1,2...)&#xff0c;若级数绝对收敛&#xff0c;则称随机变量X的数学期望存在&#xff0c;并将的和称为随机变量X的数学期望&#xff0…

5.5.7、【AI技术新纪元:Spring AI解码】Redis

Redis Redis 是一款开源(BSD 许可)的内存数据结构存储系统,可用作数据库、缓存、消息代理以及流处理引擎。Redis 提供了诸如字符串、哈希表、列表、集合、带范围查询的有序集合、位图、HyperLogLogs、地理空间索引和流等多种数据结构。 Redis 向量搜索 Redis 向量搜索与查…

【C++】每日一题 位1的个数

编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 ‘1’ 的个数&#xff08;也被称为汉明重量&#xff09;。 #include <iostream> #include <cstdint>int hammingWeight(uint3…

汇编语言中的MVC

一 MVC指令 1&#xff0e;移动字符串指令MVC 移动字符串指令MVC的格式为&#xff1a; MVC D1(L,B1),D2(B2) (移动字符串) 功能&#xff1a;&#xff08;D1&#xff08;B1&#xff09;&#xff09; ← &#xff08;D2&#xff08;B2&#xff09;&#xff09; L个字符 指令的执行…