recastnaviation: 点到线段的距离

最近在阅读RecastNavigation的源码过程中,发现很多基础几何计算函数,虽然接口封装得很好,但是内在的实现还是需要琢磨研究,它是三维几何计算的基础。以下内容为学习了解的过程,仅作分享记录,如有错误,欢迎指正。

  1. 准备知识:点积(Dot Product, 别名为:点乘,内积)
    1. 定义:点积具有两种方式表达,分别为代数方式和几何方式。这两种方式在计算点到线段距离均会使用到,故先作了解。
      1. 代数方式:
        在这里插入图片描述

      2. 几何定义:在欧几里得空间中,点积可以直观地定义为
        在这里插入图片描述

    2. 点积的几何意义:第一个向量在第二个向量上的投影
  2. 如何计算点到线段的最短距离
    点到线段的最短距离,存在以下三种情况,d为最短距离。
    在这里插入图片描述

由于存在以上三种情况,如果能通过统一的公式处理便最好了。通过上图的分析,计算AB向量在AC上的投影,可以得出投影AD向量,对AD向量分析从而得到判断结果。
以下来推导一下AD向量的过程。求AD向量,可以根据公式在这里插入图片描述,由于AC是已知的,故求AD向量的长度即可。在这里插入图片描述

  1. Recast Navigation源码分析
static float distancePtSeg(const float* pt, const float* p, const float* q)
{
	float pqx = q[0] - p[0];
	float pqy = q[1] - p[1];
	float pqz = q[2] - p[2];
	float dx = pt[0] - p[0];
	float dy = pt[1] - p[1];
	float dz = pt[2] - p[2];
	float d = pqx*pqx + pqy*pqy + pqz*pqz; // qp线段长度的平方, 为上图的AC向量长度
	// p_pt向量和p_q向的点积的代数定义公式(ref::https://zh.wikipedia.org/wiki/%E7%82%B9%E7%A7%AF)
	// p_pt·q_p = a0*b0 + a1*b1 + a2*b2
	// p_pt·q_p = |p_pt| * |q_p| * Cosθ
	float t = pqx*dx + pqy*dy + pqz*dz;	   // 为上图t向量的分子表达式
	if (d > 0)
		t /= d;
	if (t < 0)
		t = 0;
	else if (t > 1)
		t = 1;
	
	// 当t为0的时候, 计算pt和p的距离(0代入公式)
	// 当t为1的时候,计算pt和q的距离(把t=1, pqx, pqx, pqz代码公式, 则可以把p[0], p[1], p[2]消除), dx = q[0] - pt[0]; dy = q[1] - pt[1]; dz = q[2] - pt[2];
	// 当t为0<=t<=1时, 计算pt和垂足的距离.
	dx = p[0] + t*pqx - pt[0];
	dy = p[1] + t*pqy - pt[1];
	dz = p[2] + t*pqz - pt[2];
	
	// 最终计算结果为距离的平方和
	return dx*dx + dy*dy + dz*dz;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值