大家好,我是前端西瓜哥。
工作中遇到的一个平面几何问题,记录一下。
问题
已知点 A、B、C 的坐标,以 B 为垂足绘制 AB 的垂线将二维平面分成两个区域,问 C 是否在 A 所在的区域。
整了半天,发现解法很简单。
问题等价于判断向量 BA 和 BC 的夹角是否小于 90 度。
这个就很容易联想到 向量的点积公式。
变形为:
cos 为两个向量的夹角,夹角的范围为 0 到 180 度。
从图可知(只看 0 到 180 的区间),cos 如果为正数,说明夹角在 0 到 90 度范围;如果是负数,夹角在 90 到 180 度范围。
向量 a 和向量 b 的模都是正数,不影响正负,所以 cos 的正负符号只和 ab 向量的点积的正负有关。
所以,我们得到:两向量点积为正数,说明它们夹角小于 90 度;如果为负数,说明它们夹角大于 90 度。
算法实现
代码语言:javascript复制const isSideOfLineCloseA = (a, b, c) => {
const ba = { x: a.x - b.x, y: a.y - b.y };
const bc = { x: c.x - b.x, y: c.y - b.y };
return dotProduct(ba, bc) > 0;
};
const dotProduct = (a, b) => {
return a.x * b.x a.y * b.y;
};
线上 demo
我还写了个可互动 demo:
https://codesandbox.io/s/gtnhnr
(以为会很复杂,专门写来测试的...)
结尾
点积的特性在计算机图形学使用的地方相当多。
除了判断向量夹角小于还是小于 90 度,还很很多的其他的场景。
比如直接计算两向量的夹角,或是计算投影长度,可用于分离轴定理判断两个凸多边形是否碰撞。
我是前端西瓜哥,欢迎关注我,学习更多解析几何知识。