《点和直线投影及位置关系》

文章目录


再简单的问题,也需要认真推导!

直线方程

  • 点斜式: y − y 0 = k ( x − x 0 ) y - y_0 = k(x-x_0) y−y0​=k(x−x0​)
  • 斜距式: y = k x + b y=kx+b y=kx+b
  • 两点式: x − x 1 x 2 − x 1 = y − y 1 y 2 − y 1 \frac{x-x_1}{x_2-x_1} = \frac{y-y_1}{y_2-y_1} x2​−x1​x−x1​​=y2​−y1​y−y1​​ (不包括垂直坐标轴直线)
  • 截距式: x a + y b = 1 \frac{x}{a} + \frac{y}{b}=1 ax​+by​=1
  • 一般式: A x + B y + C = 0 Ax+By+C=0 Ax+By+C=0 (AB不同时为0)
  • 已知直线上两点 P 1 ( x 1 , y 1 ) P_1(x_1,y_1) P1​(x1​,y1​) 和 P 2 ( x 2 , y 2 ) P_2(x_2,y_2) P2​(x2​,y2​),和直线外一点 P 3 ( x 3 , y 3 ) P_3(x_3,y_3) P3​(x3​,y3​)
    • 求投影点 P 0 ( x 0 , y 0 ) P_0(x_0,y_0) P0​(x0​,y0​) 坐标
    • 求点和直线位置关系

点在直线投影

直线求交点

$$
P_1P_2: y=k_{12}x+b_{12} \
P_0P_3: y=k_{03}x+b_{03} \

\begin{cases}
x_1,x_1 = x_2 \
y_1,y_1 = y_2 \
x = \frac{b_{03} - b_{12}}{k_{12} - k_{03}},other
\end{cases}
$$

def cal_proj1(P1, P2, P3):
    if P1[0] == P2[0]:
        x = P1[0]
        y = P3[1]
    elif P1[1] == P2[1]:
        x = P3[0]
        y = P1[1]
    else:
        k_12 = (P2[1]-P1[1]) / (P2[0] - P1[0])
        b_12 = P1[1] - k_12 * P1[0]
        k_03 = -1/k_12
        b_03 = P3[1] - k_03 * P3[0]
        x = (b_03 - b_12) / (k_12 - k_03)
        y = k_12 * x + b_12
    return [x, y]

向量点积

$$
k * \vec{P_{12}} = \vec{P_{10}} \
k = \frac{|\vec{P_{10}}|}{|\vec{P_{12}}|} = \frac{|\vec{P_{13}}| * cos(∠P_3P_1P_2)}{|\vec{P_{12}}|} = \frac{\vec{P_{13}}.\vec{P_{12}}}{|\vec{P_{12}}|^2} \

P_0 = k * \vec{P_{12}} + P_1
$$

def cal_proj2(P1, P2, P3):
    P_12 = [P2[0]-P1[0], P2[1]-P1[1]]
    P_13 = [P3[0]-P1[0], P3[1]-P1[1]]
    k = (P_12[0] * P_13[0] + P_12[1] * P_13[1]) / (math.pow(P_12[0], 2) + math.pow(P_12[1], 2))
    x = k * P_12[0] + P1[0]
    y = k * P_12[1] + P1[1]
    return [x, y]

点和直线关系

  • 点在直线上
  • 点在直线左右
  • 点在直线上下

直线方程

  • 求直线方程
    • 已知x,求y估计和y关系
    • 已知y,求x估计和x关系
def lf_relation_between_line_and_point(P1, P2, P3):
    if P1[0] == P2[0]:
        if P3[0] == P1[0]:
            return 0
        elif P3[0] < P1[0]:
            return -1 # left
        else:
            return 1 # right
    elif P2[1] - P1[1] == 0:
        # 水平无左右?
        return 0
    else:
        k = (P2[1] - P1[1]) / (P2[0] - P1[0])
        b = P1[1] - k*P1[0]
        x_ = (P3[1] - b) / k
        if x_ == P3[0]:
            return 0
        elif x_ < P3[0]:
            return 1
        else:
            return -1


def tb_relation_between_line_and_point(P1,P2,P3):
    if P2[0] - P1[0] == 0:# 垂直无上下?
        return 0
    k = (P2[1] - P1[1]) / (P2[0] - P1[0])
    b = P1[1] - k * P1[0]
    y_ = k * P3[0] + b
    if y_ == P3[1]:
        return 0
    elif y_ < P3[1]:
        return -1 # bottom
    else:
        return 1 # up

向量叉积

  • 通过它的符号判断两矢量相互之间的顺逆时针关系

若 P × Q > 0 , 则P在Q的顺时针方向。
若 P × Q < 0 , 则P在Q的逆时针方向。
若 P × Q = 0 , 则P与Q共线,但可能同向也可能反向。

  • 满足右手螺旋准则
def lf_relation_between_line_and_point2(P1,P2, P3):
    if P1[1] == P2[1]:
        # 水平无左右
        return 0
    # 确定vector方向
    elif P1[1] > P2[1]:
        v1 = [P1[0] - P2[0], P1[1] - P2[1]]
        v2 = [P3[0] - P2[0], P3[1] - P2[1]]
    elif P1[1] < P2[1]:
        v1 = [P2[0] - P1[0], P2[1] - P1[1]]
        v2 = [P3[0] - P1[0], P3[1] - P1[1]]
    # v1 x v2
    A_cross_B = v1[0] * v2[1] - v1[1] * v2[0]
    if A_cross_B > 0:
        return -1
    elif A_cross_B < 0:
        return 1
    else:
        return 0

def tb_relation_between_line_and_point2(P1,P2,P3):
    if P1[0] == P2[0]:
        # 垂直无上下
        return 0
    # 确定vector方向
    elif P1[0] > P2[0]:
        v1 = [P1[0] - P2[0], P1[1] - P2[1]]
        v2 = [P3[0] - P2[0], P3[1] - P2[1]]
    elif P1[0] < P2[0]:
        v1 = [P2[0] - P1[0], P2[1] - P1[1]]
        v2 = [P3[0] - P1[0], P3[1] - P1[1]]
    # v1 x v2
    A_cross_B = v1[0] * v2[1] - v1[1] * v2[0]
    if A_cross_B > 0:
        return -1
    elif A_cross_B < 0:
        return 1
    else:
        return 0
上一篇:Luogu P1314 [NOIP2011 提高组] 聪明的质监员


下一篇:1934. 贝茜放慢脚步