已知直线上两点a、b和直线外一点p,求p在直线ab上的投影点。
根据《计算几何之 点在直线上的投影 代码模板与证明》一文中所述,p的投影点p’就是a+
x
⃗
\vec x
x (直线的点向式),所以我们只要求出
x
⃗
\vec x
x 就能求出p’了。
而
x
⃗
\vec x
x = t
v
⃗
\vec v
v ,这个t就是 ∣
x
⃗
\vec x
x ∣ 和 ∣
v
⃗
\vec v
v ∣ 的比值。假设两个向量的夹角为
θ
\theta
θ,则有:
t
=
∣
x
⃗
∣
∣
v
⃗
∣
=
∣
u
⃗
∣
∗
c
o
s
θ
∣
v
⃗
∣
t=\frac{|\vec x|}{|\vec v|}=\frac{|\vec u|*cos\theta}{|\vec v|}
t=∣v∣∣x∣=∣v∣∣u∣∗cosθ
根据向量的知识我们可以知道向量的夹角计算方式为:
c
o
s
θ
=
u
⃗
∗
v
⃗
∣
u
⃗
∣
∗
∣
v
⃗
∣
cos\theta = \frac{\vec u*\vec v}{|\vec u|*|\vec v|}
cosθ=∣u∣∗∣v∣u∗v
因此,t的解算可以优化为:
t
=
∣
u
⃗
∣
∗
c
o
s
θ
∣
v
⃗
∣
=
∣
u
⃗
∣
∣
v
⃗
∣
∗
u
⃗
∗
v
⃗
∣
u
⃗
∣
∗
∣
v
⃗
∣
=
u
⃗
∗
v
⃗
∣
v
⃗
∣
2
t=\frac{|\vec u|*cos\theta}{|\vec v|}=\frac{|\vec u|}{|\vec v|}*\frac{\vec u*\vec v}{|\vec u|*|\vec v|}=\frac{\vec u*\vec v}{|\vec v|^2}
t=∣v∣∣u∣∗cosθ=∣v∣∣u∣∗∣u∣∗∣v∣u∗v=∣v∣2u∗v
于是乎,我们就可以得到向量
x
⃗
\vec x
x:
x
⃗
=
t
∗
v
⃗
=
u
⃗
∗
v
⃗
∗
v
⃗
∣
v
⃗
∣
2
\vec x = t*\vec v = \frac{\vec u*\vec v*\vec v}{|\vec v|^2}
x=t∗v=∣v∣2u∗v∗v
由此,我们就可以计算出所需要的向量
x
⃗
\vec x
x,但是某些时候我们只知道向量的一个端点以及它的夹角,是否有更为方便的方式使用上述的式子呢?对于上述式子,我们还可以将其进一步简化。对于向量
v
⃗
\vec v
v而言,其可以简写成:
v
⃗
=
∣
v
⃗
∣
∗
e
⃗
\vec v =|\vec v|*\vec e
v=∣v∣∗e
其中,
e
⃗
\vec e
e为
v
⃗
\vec v
v的单位向量。
因此,向量
x
⃗
\vec x
x也可以写成:
x
⃗
=
t
∗
v
⃗
=
u
⃗
∗
e
⃗
∗
e
⃗
\vec x = t*\vec v = {\vec u*\vec e*\vec e}
x=t∗v=u∗e∗e
注意这里的运算方式,前面的
u
⃗
∗
e
⃗
\vec u*\vec e
u∗e代表的是向量的点乘,因此得到的是一个具体的数,数再乘以向量最后得到一个新的向量。因此,通过这种方式我们也可以使用这种方式来计算它的投影向量。
因此,对于最开始的问题,关于点p在向量上的投影点,其计算方式可以写为:
p
′
=
p
+
x
⃗
=
p
+
u
⃗
∗
e
⃗
∗
e
⃗
p' =p+\vec x = p+{\vec u*\vec e*\vec e}
p′=p+x=p+u∗e∗e
简单的代码实现:
Vec2f vec;//向量
Vec2f P;//向量外的点
Vec2f P_pro;//投影点
theta = 1.2;//向量的夹角
vec[0] = 4.3;//向量上的一个点
vec[1] = 2.2;
P[0] = 1;
P[1] = 0;
Vec2f e;//单位向量
e[0] = cos(theta);
e[1] = sin(theta);
Vec2f u;
u = P-vec;//向量U,终点减起点
P_pro = vec+(u.dot(e))*e;
得到的结果如下:
图中箭头代表的是向量,左侧的紫色球体代表平面上的一点,右下方的紫色球体代表该点在向量上的投影位置。
例如我们修改向量的方向及位置:
theta = 0.2;//向量的夹角
vec[0] = 1.3;//向量上的一个点
vec[1] = 0.2;
则会得到新的位置关系:
从上述的结果来看原式子的结论应该是没有问题的。
补充知识点:如何判断点在向量的左侧还是右侧?
根据夹角的计算方式:
c
o
s
θ
=
u
⃗
∗
v
⃗
∣
u
⃗
∣
∗
∣
v
⃗
∣
cos\theta = \frac{\vec u*\vec v}{|\vec u|*|\vec v|}
cosθ=∣u∣∗∣v∣u∗v
由于分母为模长,必定为正数,所以角度的正负由分子决定,因此,根据向量的点乘结果即可以判断点在向量的左侧还是右侧。
参考:
计算几何之 点在直线上的投影 代码模板与证明
向量点乘(内积)和叉乘(外积、向量积)概念及几何意义解读
Numpy计算给定线段上点的投影位置(x,y)
点在直线的投影坐标 n维向量投影坐标 几何投影坐标