计算空间中两线段之间的距离

article/2025/8/31 18:11:45

最近在建立气凝胶的有限元模型中需要计算每两根纤维(线段)之间的距离,最初参考的两篇文章确实提供了关于一些数值方法的计算思路(文章1 && 文章2),但忽略了线段距离问题的理论推导,导致无法用参数 t t t 正确描述两目标线段!所求得的结果错误。本文从理论推导和程序实现两方面来说明求空间线段之间距离的方法。

理论推导

空间直线的参数方程

如果一个非零向量平行于一条已知直线,这个向量就叫做这条直线的方向向量
由于过空间一点可作而且只能作一条直线平行于一已知直线,所以当直线 L L L上一点 M 0 ( x 0 , y 0 , z 0 ) M_{0}\left(x_{0},y_{0},z_{0}\right) M0(x0,y0,z0)和它的一方向向量 s = ( m , n , p ) \boldsymbol{s}=\left(m,n,p\right) s=(m,n,p)为已知时,直线 L L L的位置就完全确定了。下面我们来建立这直线的方程。图1
设点 M ( x , y , z ) M\left(x,y,z\right) M(x,y,z)是直线 L L L上的任意一点,那么向量 M 0 M → \overrightarrow{M_{0}M} M0M L L L的方向向量 s \boldsymbol{s} s平行(如上图所示)。所以两向量的对应坐标成比例,由于 M 0 M → = ( x − x 0 , y − y 0 , z − z 0 ) , s = ( m , n , p ) \overrightarrow{M_{0}M}=\left(x-x_{0},y-y_{0},z-z_{0}\right),\boldsymbol{s}=\left(m,n,p\right) M0M =(xx0,yy0,zz0)s=(m,n,p),从而有
x − x 0 m = y − y 0 n = z − z 0 p \frac{x-x_{0}}{m}=\frac{y-y_{0}}{n}=\frac{z-z_{0}}{p} mxx0=nyy0=pzz0

反过来,如果点 M M M不在直线上,那么由于 M 0 M → \overrightarrow{M_{0}M} M0M s \boldsymbol{s} s不平行,这两向量的对应坐标就不成比例。因此上式方程组就是直线L的方程,叫做直线的对称式方程点向式方程

由直线的对称式方程容易导出直线的参数方程。如设

x − x 0 m = y − y 0 n = z − z 0 p = t \frac{x-x_{0}}{m}=\frac{y-y_{0}}{n}=\frac{z-z_{0}}{p}=t mxx0=nyy0=pzz0=t

那么
{ x = x 0 + m t y = y 0 + n t z = z 0 + p t t ∈ ( − ∞ , + ∞ ) \begin{cases} \begin{array}{c} x=x_{0}+mt\\ y=y_{0}+nt\\ z=z_{0}+pt \end{array} & t\in\left(-\infty,+\infty\right)\end{cases} x=x0+mty=y0+ntz=z0+ptt(,+)

上式就是直线的参数方程

线段的参数方程

A ( x 1 , y 1 , z 1 ) A\left(x_{1},y_{1},z_{1}\right) A(x1,y1,z1) B ( x 2 , y 2 , z 2 ) B\left(x_{2},y_{2},z_{2}\right) B(x2,y2,z2)为线段 L L L的两端点,则线段 L L L的方向向量 s = ( x 2 − x 1 , y 2 − y 1 , z 2 − z 1 ) \boldsymbol{s}=\left(x_{2}-x_{1},y_{2}-y_{1},z_{2}-z_{1}\right) s=(x2x1,y2y1,z2z1),点 M ( x , y , z ) M\left(x,y,z\right) M(x,y,z)是线段 L L L上的任意一点,则线段的参数形式为

{ x = x 1 + ( x 2 − x 1 ) t y = y 1 + ( y 2 − y 1 ) t z = z 1 + ( z 2 − z 1 ) t t ∈ [ 0 , 1 ] \begin{cases} \begin{array}{c} x=x_{1}+\left(x_{2}-x_{1}\right)t\\ y=y_{1}+\left(y_{2}-y_{1}\right)t\\ z=z_{1}+\left(z_{2}-z_{1}\right)t \end{array} & t\in\left[0,1\right]\end{cases} x=x1+(x2x1)ty=y1+(y2y1)tz=z1+(z2z1)tt[0,1]

线段之间距离的数值解法

线段之间距离的数值解法是将参数 t t t 在区间 [ 0 , 1 ] [0,1] [0,1] 上均匀离散,每个 t t t 的取值,对应线段上的一个点。将求线段间的距离转化为求两线段上点的距离集合的最小值。(两线段上点的距离集合是指 a a a 线段的每个离散点与 b b b 线段上的所有离散点之间的距离,若设 a a a 线段上的离散点个数为 m m m b b b 线段上的离散点个数为 n n n ,则两线段上点的距离集合元素的个数为: m × n m\times n m×n)。该方法所求出的线段之间的距离为近似值,所求结果的精度取决于线段上离散点的数量。

程序实现

double LinesDistance_another_method(double *line1,double *line2)
{int i,j,m,n;double *t1,*t2,*x1,*y1,*z1,*x2,*y2,*z2,**juli,min_value;double DirectionVector_m1,DirectionVector_n1,DirectionVector_p1;double DirectionVector_m2,DirectionVector_n2,DirectionVector_p2;t1 = new double [11];t2 = new double [11];x1 = new double [11];x2 = new double [11];y1 = new double [11];y2 = new double [11];z1 = new double [11];z2 = new double [11];DirectionVector_m1=line1[3]-line1[0];DirectionVector_n1=line1[4]-line1[1];DirectionVector_p1=line1[5]-line1[2];// 	printf("line1: \n");// 	printf("x1=%lf,x2=%lf\n",line1[0],line1[3]);// 	printf("x2-x1=%lf\n",DirectionVector_m1);for (i = 0;i < 11;i++){t1[i]=0.1*i;/*		printf("t1[%d]=%lf\n",i,t1[i]);*/}for (i = 0;i < 11;i++){x1[i]=line1[0]+DirectionVector_m1*t1[i];y1[i]=line1[1]+DirectionVector_n1*t1[i];z1[i]=line1[2]+DirectionVector_p1*t1[i];/*		printf("x1[%d]=%lf\n",i,x1[i]);*/}DirectionVector_m2=line2[3]-line2[0];DirectionVector_n2=line2[4]-line2[1];DirectionVector_p2=line2[5]-line2[2];// 	printf("line1: \n");// 	printf("x1=%lf,x2=%lf\n",line2[0],line2[3]);// 	printf("x2-x1=%lf\n",DirectionVector_m2);for (i = 0;i < 11;i++){t2[i]=0.1*i;/*		printf("t2[%d]=%lf\n",i,t2[i]);*/}for (i = 0;i < 11;i++){x2[i]=line2[0]+DirectionVector_m2*t2[i];y2[i]=line2[1]+DirectionVector_n2*t2[i];z2[i]=line2[2]+DirectionVector_p2*t2[i];/*		printf("x2[%d]=%lf\n",i,x2[i]);*/}n=11;//n=length(t1);m=11;//m=length(t2);juli = new2DDouble(n,m);for (i = 0;i < n;i++){for (j = 0;j < m;j++){juli[i][j]=sqrt(pow((x2[j]-x1[i]),2)+pow((y2[j]-y1[i]),2)+pow((z2[j]-z1[i]),2));}}min_value=juli[0][0];for (i = 0;i < n;i++){for (j = 0;j < m;j++){if (min_value>juli[i][j]){min_value=juli[i][j];}}}freeDoubleArray2(juli,n);juli = NULL;delete [] t1;t1 = NULL;delete [] t2;t2 = NULL;delete [] x1;x1 = NULL;delete [] x2;x2 = NULL;delete [] y1;y1 = NULL;delete [] y2;y2 = NULL;delete [] z1;z1 = NULL;delete [] z2;z2 = NULL;return min_value;
}
double **new2DDouble(int col,int lin)
{double **newArray;newArray = new double *[col];for(int i=0;i<col;i++){  newArray[i]=new double[lin];}for(int i=0;i<col;i++){  for(int j=0;j<lin;j++){newArray[i][j]=0.0;}}return newArray;
}
void freeDoubleArray2(double **Array,int NIFF0)
{int i;for(i=0;i<NIFF0;i++){delete [] Array[i];				}delete [] Array;Array = NULL;
}

方法的验证

在纤维组成的气凝胶模型中,为了使纤维之间能够连接到一起,就需要严格控制纤维之间的距离。所以引用这里的求线段之间距离的方法,来筛选出满足距离要求的纤维。那么若纤维之间不能很好的相连,则说明距离求解有误。下图为气凝胶模型的一小部分结构,对其进行有限元的模态分析来检验模型的连接状态。由其云图结果可知该模型已经连接成为一整体,该方法有效!在这里插入图片描述


http://chatgpt.dhexx.cn/article/tWNbEDyT.shtml

相关文章

空间两个直线之间的距离和公垂线

已知 直线1&#xff1a;直线任意一点 P 1 P_1 P1​直线方向 V 1 V_1 V1​ (单位向量) 直线2&#xff1a;直线任意一点 P 2 P_2 P2​直线方向 V 2 V_2 V2​ (单位向量) 求解过程 需要用到点到直线的距离和垂足相关内容&#xff0c;参考 这里 下文中 ⋅ \centerdot ⋅代表点…

两点间距离、点到直线距离、点到线段距离、线段到线段距离

两点之间的距离 直接运用两点间距离公式 (x2-x1)^ 2(y2-y1)^ 2开根号 //两点间距离 double getDistancePP(Point a,Point b) { //这个代码是部分代码,有些逻辑没有展现完全,大家往下看!Point c(b.x-a.x,b.y-a.y);//返回一个新的点return c.abs();//取模 }点到直线距离 通常给出…

两平行平面间的距离

两平行平面方程为AxByCzD10&#xff0c;AxByCzD20 转载于:https://www.cnblogs.com/qiu-hua/p/8006040.html

两条平行线相交于一点

2019独角兽企业重金招聘Python工程师标准>>> 欧几里德几何说&#xff0c;两条平行的直线永远无法相交&#xff0c;爱因斯坦站在宇宙空间的角度猜测两条平行线有可能能相交&#xff0c;但到底如何相交&#xff0c;爱因斯坦也没有给出证明&#xff0c;科学家们至今也无…

【opencv】两条平行线之间的距离

问题&#xff1a;一张输入图片&#xff0c;图片上有两条平行线&#xff0c;求出这两条平行线之间的距离 解决思路&#xff1a; 1. 对图像中的直线进行细化 2. 提取直线的轮廓坐标 3. 对轮廓上的坐标进行直线集合&#xff0c;从而得到直线方程 4. 计算两条直线之间的距离 …

OpenCV计算两条平行线之间的距离

代码来自www.opencvchina.com #include "cv.h" #include "highgui.h" #include "cxcore.h" #include <stdlib.h> #include <stdio.h>#ifndef LINESDISHEADER#define LINESDISHEADER//对输入图像进行细化 void ThinImage(IplImage* s…

用vue实现tab切换

用vue实现tab切换 html代码 <div id"app"><ul class"tab-tilte"><li click"cur0" :class"{active:cur0}">html</li><li click"cur1" :class"{active:cur1}">css</li><li…

tab切换(用jQuery实现)?

页面中经常用到的tab栏&#xff0c;来分类展示内容 我认为掌握tab栏切换算是从静态页面到动态页面所迈出的第一步&#xff0c;并且在以后的工作中(jQuery框架开发)会作为jQuery中的常用事件和方法&#xff0c;反复的使用&#xff0c;所以掌握tab栏切换至关重要&#xff01;&am…

JQUERY实现TAB切换

博主是一枚前端小菜鸟&#xff0c;因为挺长时间没接触页面布局了&#xff0c;居然连tab栏切换都给忘了&#xff0c;后来博主看了一些前端资料还有书&#xff0c;发现网上的很多方法都杂乱无章&#xff0c;看的云里雾里的&#xff0c;冗余代码太多&#xff0c;这让新手小白会很苦…

React实现tab切换

下面来编写一个tab选项卡切换效果&#xff0c;效果如下图所示&#xff1a; 下面我放上该组件的代码&#xff1a; import React, { Component } from react; import { Link } from react-router; import ../scss/base.scss; import ../scss/tab.scss;class TabController exten…

vue实现Tab切换功能

在项目开发中&#xff0c;我们经常会碰到Tab切换的功能&#xff0c;而在Vue中想实现这样的功能也应该有很多种&#xff0c;常用的三种应该是 Tab路由切换、Tab动态组件切换、通过v-show设置Tab显示隐藏。每种方法实现起来其实都不难&#xff0c;看看官网介绍或看几篇博客应该就…

tab切换效果

1.效果图 2.分析步骤 1.首先写vue先引入&#xff1a;<script src"https://cdn.jsdelivr.net/npm/vue2.6.14/dist/vue.js"></script> 2.接着写静态布局 3.挂载dom 4.添加指令 5.肯定要储存数据 6. 最后效果实现 3.代码块部分 按步骤操作 1.首先&#xf…

vue中如何实现tab切换功能?

一、v-show控制内容切换 1&#xff09;简单版原理&#xff1a;用点击事件改变num值作为开关&#xff0c;控制tab样式和内容显示隐藏。 2&#xff09;数据渲染原理&#xff1a;主要利用v-for绑定的index来控制&#xff0c;跟上面差不多。 二、组件切换。 知识点主要是vue中is的…

点击tabs切换不同的内容

1.通过v-for遍历posts,然后渲染数据 2.定义currentTabs变量 3.运用computed计算属性 4.点击按钮时&#xff0c;切换下边的内容 5.点击切换tabs时&#xff0c;高亮当前tabs 4.将切换tabs的文件封装成组件&#xff0c;可以使用keep-alive进行缓存数据 5.使用keep-alive触发的生命…

Tab选项卡切换

Tab选项卡切换 基本代码 HTML代码&#xff1a; <div id"notice" class"notice"><!-- 标题--><div id"notice-tit" class"notice-tit"><ul><li><a href"#">公告</a></li>…

【JS实现tab切换】

JavaScript实现tab切换。 点击科技显示图一, 点击探索显示图二。 body部分&#xff1a; <div class"box"><ul><li class"active">科技</li><li>探索</li></ul><ol><li class"active">科…

Tab页面切换

页面效果如图 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta http-equiv"X-UA-Compatible" content"IEedge"> <meta name"viewport" content"widthdevice-…

Vue实现Tab切换效果

通过Vue实现简单的Tab切换 实现思路是点击上方的标题&#xff0c;下方的内容随之发生改变&#xff0c;上方和下方用的是两个块&#xff0c;是兄弟节点&#xff0c;所以需要点击tab标题和下方内容一一对应&#xff0c;基予两个模块若下标相同是一个内容实现的。Tab切换第一步先…

html的tab切换

离开学还有10天了&#x1f630; 今天再水一篇博客 &#xff08;如图&#xff09; 通过点击来切换tab。 具体思路十分简单&#xff0c;将这些都先包含进一个大的div 先是html部分 <div class"body1"><div class"game"><ul><li>…

Vue实现选项卡切换,tab切换

1、实现tab切换就是 单击一个选项卡显示其对应的内容&#xff0c;且被点击的选项卡改变颜色&#xff0c;下面有两种实现方法&#xff08;都不要忘了vue.js的目录要写正确&#xff09; 2、第一种方法效果图 这个没什么可说的&#xff0c;直接看代码吧&#xff08;两种方式&…