[图形学] 射线和线段之间的最小距离

本文详细介绍了Unity引擎中Spline功能的一个函数,该函数用于计算射线与线段之间的最短距离,并确定该点在线段上的位置。通过向量运算和坐标系变换,解释了如何通过射线起点、方向和线段起点、方向找到最短距离点,并返回一个0-1之间的参数表示该点在线段上的位置。此外,文章还探讨了不同方向移动线段时对最短距离点影响的几何原理。

1 说在前面

本文的主要内容来自于Unity引擎中Spline功能的一个函数,一开始我难以理解这几个向量运算的作用和几何意义,经过一番思考后总结如下:
该段代码实际上更像是两个直线之间寻找最短距离,然后判断该距离对应的点在其中一条直线(代码中称为线段)上的位置(线段前、线段中、线段后);由于代码中以射线-线段的关系来描述这个问题,本文中也统一以射线和线段称呼两者的关系,在以后再次提到时就不做补充说明了;

函数的具体内容为:

/// <summary>
/// Returns the parameterization of a ray line projection. The parameter will be negative if the nearest point
/// between the ray/line is negative to 'lineOrigin', and greater than 1 if nearest intersection is past the end
/// off the line segment (lineOrigin + lineDir).
/// </summary>
/// <param name="ro">The ray origin point.</param>
/// <param name="rd">The ray direction (normalized vector).</param>
/// <param name="lineOrigin">Line segment first point.</param>
/// <param name="lineDir">Line segment direction (with magnitude).</param>
/// <returns>The parameter of a ray line projection.</returns>
public static float RayLineParameter(float3 ro, float3 rd, float3 lineOrigin, float3 lineDir)
{
   
   
    var v0 = ro - lineOrigin;
    var v1 = math.cross(rd, math.cross(rd, lineDir));
    // the parameter of a ray to line projection will be negative if the intersection is negative to line
    // direction from 'a', and greater than 1 if intersection is past the line segment end 'b'
    return math.dot(v0, v1) / math.dot(lineDir, v1);
}

该函数实现了:输入一个射线的起点与方向:ro、rd,以及一个线段的起点和朝向(包括了线段的长度)。返回一个float数值,表示射线到线段的最小距离对应的点在线段上的位置,(0-1)之间表示在线段上,(-∞,0)表示在线段起点之前,(0, +∞)表示在线段重点之,该数值约接近0表示距离线段起点越近,越接近1表示距离线段终点越近。一些特例如下图所示:
在这里插入图片描述
需要注意,射线和线段都是用float3表示的,它们存在于三维空间中,以上例子只不过是刚好同处于一个二维平面下的特例。

2 运算

该计算涉及两个向量:射线向量和线段向量,分别用r和l表示,进一步的,将向量的首末端点表示为r0,r1r_0, r_1r0,r1l0,l1l_0, l_1l0,l1,如下图所示:
在这里插入图片描述

这段代码其实很短,只计算了两个中间变量v0,v1v_0, v_1v0,v<

「LLM那些事」系列第 4 篇《上下文窗口的边界》,文章连接:https://blog.csdn.net/houwenjin/article/details/163999753。 演示什么:在「预测」Sheet 的黄色格子里输入一句话(默认「来泡一杯」),四个「模型」——分别只统计最后 1 / 2 / 3 / 4 个字的 n-gram 查表——同时预测下一个字。同一个输入,看的上下文越长,候选越少、预测越确定: ┌────────────────┬──────────┬───────────────┬──────┐ │ 只看最后几个字 │ 用的前缀 │ 候选下一字数 │ 预测 │ ├────────────────┼──────────┼───────────────┼──────┤ │ 1 个 │ 杯 │ 3(茶/子/水) │ 模糊 │ ├────────────────┼──────────┼───────────────┼──────┤ │ 2 个 │ 一杯 │ 2(茶/水) │ 收窄 │ ├────────────────┼──────────┼───────────────┼──────┤ │ 3 个 │ 泡一杯 │ 1(茶) │ 确定 │ ├────────────────┼──────────┼───────────────┼──────┤ │ 4 个 │ 来泡一杯 │ 1(茶) │ 确定 │ └────────────────┴──────────┴───────────────┴──────┘
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值