2021-11-18.使用Python处理一些直线问题并用matplotlib画图

最近处理一些问题,涉及到对直线进行处理。对于十几年不接触数学的人而言,有些意思。

我想要实现的有以下:

  1. 已知两个点(x1, y1), (x2, y2),求直线方程;
  2. 已知四个点(x1, y1), (x2, y2), (p1, q1), (p2, q2),求(x1, y1), (x2, y2)组成的直线与(p1, q1), (p2, q2)组成直线,这两条直线的交点;
  3. 过该交点,平分交点的角,形成的直线,求该直线的方程;
  4. 最好能画出来上述的图。

需要准备的数学知识,可以参考维基或数学课本,也可以自己算出来。简单截图如下:

  1. 直线定义,两点式、斜截式和一般式


  1. 两个直线的交点


  2. 平面2点距离


  3. 角平分线定理


备注:实际上也可以求的交点的夹角后,通过一条直线旋转后生成方程。但是推导起来有点困难,所以没有采用。过后我如果解决了,会再写上。

步骤如下:

  1. 求交点;
  2. 在交点的左右取x值,计算出对应的y值,形成2个点后,直线的方程就有了。

下面是代码(简化处理,没有考虑平行的情况)

# 导入必要的包
import numpy as np
from matplotlib import pyplot as plt
import math

# 过直线A的两点
x1, y1 = 2, 3
x2, y2 = 7, 10

# 过直线B的两点
p1, q1 = 4, 8
p2, q2 = 6, 3

# 绘制直线A上的点
plt.plot(x1, y1, "ob")
plt.plot(x2, y2, "ob")

# 绘制直线A上的点
plt.plot(p1, q1, "or")
plt.plot(p2, q2, "or")

# 定义求斜率的方法
def get_k(x1,y1,x2,y2):
    k = (y1-y2)/(x1-x2)
    return k

# 定义求截距的方法
def get_b(x1,y1,x2,y2):
    b = (x1*y2-x2*y1)/(x1-x2)
    return b

# 绘制直线A
k1 = get_k(x1,y1,x2,y2)
b1 = get_b(x1,y1,x2,y2)
x_1 = np.arange(1, 10, 0.2)
y_1 = k1 *x_1 +b1 
plt.plot(x_1 , y_1 , linewidth=0.5)

# 绘制直线B
k2  = get_k(p1,q1,p2,q2)
b2 = get_b(p1,q1,p2,q2)
x_2 = np.arange(1, 10, 0.2)
y_2 = k2 *x_2 +b2 
plt.plot(x_2, y_2, linewidth=0.5)

# 定义矩阵运算,方便调用
def mat(a, b, c, d):
    return a*d-b*c

# 定义获取一般式ABC的方法
def get_ABC(x1, y1, x2, y2):
    A = y2 - y1
    B = x1 - x2
    C = x2*y1 - x1*y2
    return A, B, C

# 分别求两条直线的ABC
A1, B1, C1 = get_ABC(x1, y1, x2, y2)
A2, B2, C2 = get_ABC(p1, q1, p2, q2)

# 求出交点并绘制
cross_x = - (mat(C1, B1, C2, B2))/(mat(A1, B1, A2, B2))
cross_y = - (mat(A1, C1, A2, C2))/(mat(A1, B1, A2, B2))
plt.plot(cross_x, cross_y, "og")

# 求三角形底边长度,随便定义个中文名函数。x是在x轴取的值,只需要在交点左右取两点即可
def get_底边长度(x, k1, b1, k2, b2):
    y1 = k1*x+b1
    y2 = k2*x+b2
    return math.fabs(y1-y2)

# 定义求距离的方法
def get_distance(x0, y0, x1, y1):
    dd = (x0-x1)**2 + (y0-y1)**2
    d = math.sqrt(dd)
    return d

# 在交点的左、右各取一个x轴位置,分别求出该x时,两条直线的y的值
x_left = cross_x - 3
y_left_1 = k1*x_left+b1
y_left_2 = k2*x_left+b2
x_right = cross_x + 3
y_right_1 = k1*x_right+b1
y_right_2 = k2*x_right+b2

# 于是一共有4个点:(x_left, y_left_1), (x_left, y_left_2), (x_right, y_right_1), (x_right, y_right_2)

# 利用角平分线定理求得在夹角平分线上的点的y值
上边长_left = get_distance(x_left, max(y_left_1, y_left_2), cross_x, cross_y)
下边长_left = get_distance(x_left, min(y_left_1, y_left_2), cross_x, cross_y)
上边长_right = get_distance(x_right, max(y_right_1, y_right_2), cross_x, cross_y)
下边长_right = get_distance(x_right, min(y_right_1, y_right_2), cross_x, cross_y)
底边长度_left = get_底边长度(x_left, k1, b1, k2, b2)
底边长度_right = get_底边长度(x_right, k1, b1, k2, b2)
上底边_left = (上边长_left * 底边长度_left)/(上边长_left+下边长_left)
y_left = max(y_left_1, y_left_2) - 上底边_left # 左边的点为(x_left, y_left)
上底边_right = (上边长_right * 底边长度_right)/(上边长_right+下边长_right)
y_right = max(y_right_1, y_right_2) - 上底边_right # 右边的点为(x_right, y_right)

# 现在夹角平分线上的2个点就有了。该直线很容易求得。顺便把这2个点也画出来
plt.plot(x_left, y_left, "og")
plt.plot(x_right, y_right, "og")
k = get_k(x_left, y_left, x_right, y_right)
b = get_b(x_left, y_left, x_right, y_right)

# 最后把直线画出来
x = np.arange(1, 10, 0.2)
y = k*x+b
plt.plot(x, y, linewidth=0.8)

结果如下图:


画出来的图看起来好像两个角不一样大。本着求真务实的精神,在用点到距离的公式验算一下。
正确的情况下,点到两条直线的距离应该相等。

# 定义计算点到直线的距离的方法
def get_点到直线距离(A, B, C, x, y):
    up = math.fabs(A*x+B*y+C)
    down = math.sqrt(A**2+B**2)
    d = up/down
    return d

d1 = line.get_点到直线距离(A1, B1, C1, x_left, y_left)
d2 = line.get_点到直线距离(A2, B2, C2, x_right, y_right)

# d1 = 2.6512291367965264
# d2 = 2.6512291367965277

d1与d2几乎相等了,看起来角不一样大,可能是由于运算的误差造成的。

以上,如果有错误,还请留言批评指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,718评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,683评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,207评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,755评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,862评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,050评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,136评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,882评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,330评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,651评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,789评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,477评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,135评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,864评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,099评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,598评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,697评论 2 351

推荐阅读更多精彩内容