计算二维/三维空间中两条线段的交点

地球屋里老师 2021-08-13 12:08:55

本例可用于求取二维或三维空间中两线段的交点,其算法原理简介如下:

1、先用参数方程表示相应的直线 x(t)=x0+(x1-x0)*t;

2、建立关于未知量t的线性方程组;

3、求系数矩阵及增广矩阵的秩,以此判断解的存在情况;

4、如果t的解存在且在范围[0,1]之内,求出交点坐标。

program test
implicit none
integer, parameter:: DIM = 3
integer stat
real p1(DIM), p2(DIM), p3(DIM), p4(DIM), p(DIM)
p1=[0,0,0]
p2=[1,1,1]
p3=[1,1,0]
p4=[0.0,0.0,1.5]
call intersectionPoint(p1, p2, p3, p4, p, stat)
if(stat==0) print*,p
pause
end program
!****************************************************************************
! 求两条线段的交点,二维:DIM=2,三维:DIM=3
! 输入:
! p1, p2            ... 线段1的两个端点
! p3, p4            ... 线段2的两个端点
! 输出
! p                 ... 交点坐标
! stat              ... 0: 有交点;1: 无交点
! author: LI xingwang, Chang'an university, China. 
!****************************************************************************
subroutine intersectionPoint(p1, p2, p3, p4, p, stat)
implicit none
integer, parameter:: DIM = 3
real, parameter:: EPS = 1.0e-7, ZERO = tiny(0.0)*100.0
real, intent(in):: p1(DIM), p2(DIM), p3(DIM), p4(DIM)
real,intent(out):: p(DIM)
integer,intent(out):: stat
real aMat(DIM,3) !augmented matrix,增广矩阵
real row(3), col(DIM), mVal
real, target:: x(2)
real, pointer:: t1, t2
integer ind(2), iRow, iCol, r1, r2, i

p = -huge(0.0); x = -huge(1.0)
r1 = -999; r2 = -999 !矩阵、增广矩阵的秩
t1 => x(1); t2 => x(2)
aMat(:,1) = p2 - p1
aMat(:,2) = p3 - p4
aMat(:,3) = p3 - p1
ind = maxloc(abs(aMat(:,1:2))) !前两列最大值所在位置
iRow = ind(1); iCol = ind(2)
mVal = aMat(iRow,iCol)

if(abs(mVal)<ZERO) then !为两点
  r1 = 0
  if(maxval(abs(aMat(:,3)))<ZERO) then
    r2 = 0
  else
    r2 = 1
  end if
  goto 100
end if

aMat = aMat / mVal !归一化
!行变换
select case(iRow)
case(2)
  row(:) = aMat(2,:)
  aMat(2,:) = aMat(1,:)
  aMat(1,:) = row(:)
case(3)
  row(:) = aMat(DIM,:)
  aMat(DIM,:) = aMat(1,:)
  aMat(1,:) = row(:)
end select
!消元
do i = 2, DIM
  aMat(i,:) = aMat(i,:) - aMat(i,iCol)*aMat(1,:)
end do
!列变换
if(iCol==2) then
  t1 => x(2); t2 => x(1)
  col = aMat(:,2)
  aMat(:,2) = aMat(:,1)
  aMat(:,1) = col
end if

iRow = 1 + maxloc(abs(aMat(2:,2)),1) !最大值所在位置
mVal = aMat(iRow,2)
!行变换
if(iRow==3) then
  row(:) = aMat(DIM,:)
  aMat(DIM,:) = aMat(2,:)
  aMat(2,:) = row(:)
end if
if(abs(mVal)>ZERO) then
  aMat(2:,:) = aMat(2:,:) / mVal !归一化
  do i = 3, DIM !消元
    aMat(i,:) = aMat(i,:) - aMat(i,2)*aMat(2,:)
  end do
end if

!第三行
if(DIM==3.and.abs(aMat(DIM,3))>ZERO) then
  r1 = 1; r2 = 3
  goto 100
end if
!第二行
if(abs(aMat(2,2))<ZERO) then
  r1 = 1
  if(abs(aMat(2,3))<ZERO) then
    r2 = 1
  else
    r2 = 2
  end if
else
  r1 = 2; r2 = 2
end if

100 stat = 1
!根据秩判断解
if(r2>r1) return !无解
select case(r1)
case(2)
  t2 = aMat(2,3) / aMat(2,2)
  t1 = aMat(1,3) - t2*aMat(1,2)
  if(-EPS<t1.and.t1<1.0+EPS.and.-EPS<t2.and.t2<1.0+EPS) stat = 0
case(1)
  t1 = aMat(1,3)
  if(-EPS<t1.and.t1<1.0+EPS) then
    stat = 0
  else
    t1 = aMat(1,3) - aMat(1,2)
    if(-EPS<t1.and.t1<1.0+EPS) stat = 0
  end if
case(0)
  t1 = 0.0
  stat = 0
end select

if(stat/=0) return
!求交点
if(associated(t1,x(1))) then
  p = p1 + (p2-p1)*t1
else
  p = p3 + (p4-p3)*t1
end if
end subroutine

 

...全文
1709 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_46580779 2021-08-13
  • 打赏
  • 举报
回复 1

非常不错,我想弄一个fortran的语言的解析的

内容概要:本文围绕基于蜣螂优化算法(DBO)的无线传感器网络(WSN)覆盖优化问题展开研究,提出了一种创新性的智能优化解决方案,并提供了完整的Matlab代码实现。研究首先分析了传统WSN覆盖优化存在的覆盖率低、能耗不均等问题,随后引入蜣螂优化算法这一新型群体智能算法,通过模拟蜣螂的生物行为机制,构建了适用于传感器节点部署优化的数学模型。文详细阐述了算法的设计思路、实现步骤及其在提高网络覆盖率、延长网络生命周期方面的有效性,同时通过仿真实验与其他主流优化算法进行了对比,验证了所提方法的优越性。; 适合人群:具备一定优化算法基础和Matlab编程能力,从事通信工程、物联网、智能优化等相关领域的研究生及科研人员。; 使用场景及目标:①解决无线传感器网络节点部署不合理导致的覆盖盲区问题;②提升网络整体覆盖性能与资源利用效率;③为智能优化算法在实际工程的应用提供可复现的研究案例和技术参考。; 阅读建议:建议读者结合文的Matlab代码进行实践操作,重点关注算法参数设置、适应度函数设计及仿真结果分析部分,同时可尝试将该算法迁移至路径规划、资源调度等其他优化场景进行拓展研究。
已经博主授权,源码转载自 https://pan.quark.cn/s/a4b39357ea24 在信息技术领域,特别是软件编程行业,微软公司推出的集成开发环境(IDE)Visual Studio,凭借其卓越的功能和广泛的适用范围,成为了众多程序员的常用工具。不过,在实际操作期间,用户可能会遭遇各种挑战,其一种较为普遍的挑战是“Visual Studio遭遇了异常情况,这或许与某个附加组件有关”。本文将详细研究这一现象的成因、潜在后果以及最终的应对措施。 ### 原因剖析 Visual Studio通过支持多种插件和附加组件来扩展其功能,这些组件通常由第三方开发者设计,旨在为用户提供更多个性化和专业化的工具。然而,这些插件的质量良莠不齐,部分可能未经过充分的测试或与特定版本的Visual Studio存在兼容性难题,从而在执行时引发异常。异常的出现可能源于以下几个因素: 1. **代码缺陷**:若附加组件的代码存在逻辑问题或资源管理不当,就可能导致运行时异常。 2. **资源竞争**:多个插件同时占用相同的资源(例如内存、文件句柄等),可能会产生资源冲突,进而触发异常。 3. **依赖不匹配**:插件可能需要特定版本的库或框架,如果系统安装的版本不一致,也可能导致异常。 4. **安全隐患**:部分插件可能存在安全漏洞,一旦被恶意利用,可能会导致更严重的问题,包括但不限于异常崩溃。 ### 后果分析 当Visual Studio遇到由附加组件引发的异常时,不仅会断当前的工作进程,降低开发效能,还可能带来以下潜在风险: 1. **数据遗失**:若异常发生在保存操作之前,可能会导致未保存的工作内容遗失。 2. **稳定性减弱**:频繁的异常会导致Visual Stud...

219

社区成员

发帖
与我相关
我的任务
社区描述
社区旨在便于Fortran编程语言交流学习,同时讨论数值计算、并行计算相关问题,共同发展fortran生态。
社区管理员
  • 地球屋里老师
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

自愿,自律,自强

试试用AI创作助手写篇文章吧