那这个呢?
- 计算 AB。
我们现在有一个从圆心指向 A 的向量(如果 B 是原点,跳过这个,只考虑点 A 一个向量)。
- 标准化。现在我们有一个明确定义的长度(长度为 1)
- 如果圆不是单位半径,则乘以半径。如果是单位半径,则跳过此。现在我们有了正确的长度。
- Invert sign (can be done in one step with 3., just multiply with the negative radius)
Now our vector points in the correct direction.
- Add B (if B is the origin, skip this).
Now our vector is offset correctly so its endpoint is the point we want.
(Alternatively, you could calculate B-A to save the negation, but then you have to do one more operation to offset the origin correctly.)
By the way, it works the same in 3D, except the circle would be a sphere, and the vectors would have 3 components (or 4, if you use homogenous coords, in this case remember -- for correctness -- setting w to 0 when "turning points into vectors" and to 1 at the end when making a point from the vector).
编辑:(
作为伪代码的回复)
假设你有一个 vec2 类,它是一个由两个浮点数组成的结构,带有用于向量减法和标量乘法的运算符(非常简单,大约十几行代码)和一个normalize
不需要的函数与乘以的简写相比inv_sqrt(x*x+y*y)
,伪代码(我的伪代码类似于 C++/GLSL 混合)可能看起来像这样:
vec2 most_distant_on_circle(vec2 const& B, float r, vec2 const& A)
{
vec2 P(A - B);
normalize(P);
return -r * P + B;
}
您将使用的大多数数学库都应该内置所有这些函数和类型。HLSL 和 GLSL 将它们作为第一类原语和内在函数。一些 GPU 甚至有专门的规范化指令。