0

我是编码新手,我目前正在创建一个程序,该程序计算一条线的斜率截距形式以及该线的 x 截距和 y 截距等信息,这些信息源自任何两个随机坐标对的值示例 (x1,y1), (x2,y2) = (1,2), (3,4) 这在 matplotlib 中呈现的内容,当绘制时是具有计算斜率的线段(此处恰好为 1 y = 1x + 1) 不跨越任何轴'。我想在它上面画另一条线,其斜率与连续的线段相同,以显示线段将穿过 x 和 y 轴的位置,但我想为随机坐标对输入的任何组合执行此操作由用户。我还想将图形设置为使用图形的原点加载(0,0)在生成时位于框架的左下方,并且在生成时没有以我的线段为中心的图形。任何帮助深表感谢。

import numpy as np
import math
x1 = float(input("Enter a x coordinate for x1: "))
y1 = float(input("Enter a y coordinate for y1: "))
x2 = float(input("Enter a x coordinate for x2: "))
y2 = float(input("Enter a y coordinate for y2: "))
m = (y2-y1)/(x2-x1)
d = math.sqrt((x2 - x1)**2 + (y2-y1)**2)
slope_multiplied_by_negative_x1 = m * (-1 * x1)
b = float(y1) + float(slope_multiplied_by_negative_x1)
b_absolute = abs(b)
result = "y = " + (str(m) + "x " if m != 0 else "")
if m == 0:
    sign = ""
elif b == 0:
    sign = ""
elif b > 0:
    sign = "+ "
else:
    sign = "- "
try: X_intercept = float((-1 * b)/m)
except ZeroDivisionError:
    X_intercept = 'n/a'
print(result + sign + ("" if b == 0 else (str(b_absolute))))
print("X intercept: " + ("0.0" if X_intercept == 0 else str(X_intercept)))
print("Y intercept: " + str(b))
print("Distance between (x1,y1) and (x2,y2): " + str(d))
x = [x1,x2]
y=[y1,y2]
t = np.arange(0.0, 2.0, 0.01)
fig, ax = plt.subplots()
plt.plot(x, y, color='c', linestyle='-', marker='o')
ax.spines['left'].set_position('zero')
ax.spines['bottom'].set_position('zero')
ax.grid()
plt.show()
4

2 回答 2

1

带端点的线段(x1,y1), (x2,y2)属于符合方程的线

(x - x1) / (x2 - x1) = (y - y1) / (y2 - y1)

首先,我们需要检查垂直和水平线的额外情况:

if x1 == x2:
    x_intercept = x1
    y_intercept does not exist 
    use screen window border coordinates to draw line
    (x1,0)-(x1,height)  

if y1 == y2:
    y_intercept = y1
    x_intercept does not exist
    use screen window border coordinates to draw line
    (0,y1)-(width,y1)  

否则,要找到与轴的交点,我们只需将y=0或代x=0入该方程即可。

x_intercept = x1 - y1 * (x2 - x1) / (y2 - y1)
y_intercept = y1 - x1 * (y2 - y1) / (x2 - x1)
draw line
(0, y_intercept) - (x_intercept, 0)  

PS 请注意,您在计算几何中很少需要斜率 - 有很多更通用的线定义方法(描述的一种,参数方法,theta-rho 方法)

于 2020-02-05T05:55:22.730 回答
0

这是一种无需过多更改原始代码的方法。它测试水平线和垂直线,并在起点和终点相等时给出结果。

通过在图中绘制一个不可见的点,点 (0,0) 被强制在图中。在每个端点和每个截距之间添加线。这也将强制两者(如果它们存在)都在地块区域中。您会注意到这将多次绘制相同的段,但它避免了太多测试而无法知道需要哪些段。绘制顺序确保 (x1,y1) 和 (x2,y2) 之间的段位于顶部。

Numpy 被删除,因为这里不需要它,但它对其他类型的曲线很有用。计算中通常不需要转换为浮点数,因为 Python3 会自动将整数转换为浮点数以进行除法运算。

可以考虑的一些扩展:

  • 测试浮点数是否相等以避免除以 0 对于大型计算产生的浮点数可能是危险的;有时浮点数几乎但不完全相等,除以它们的差异会导致溢出(或不需要的大数)
  • 要延长线直到它们接触边界,您需要求解方程以找到与四个边界中的每一个的交点并拒绝那些落在其他边界之外的交点
  • 或者,您可以画一条很长的线,然后重新应用 x 和 y 限制

以下是一些可以作为进一步实验基础的代码:

import matplotlib.pyplot as plt
import math

x1 = float(input("Enter a x coordinate for x1: "))
y1 = float(input("Enter a y coordinate for y1: "))
x2 = float(input("Enter a x coordinate for x2: "))
y2 = float(input("Enter a y coordinate for y2: "))

d = math.sqrt((x2 - x1)**2 + (y2-y1)**2)
if x2 != x1:
    m = (y2-y1)/(x2-x1)
    slope_multiplied_by_negative_x1 = m * (- x1)
    b = y1 + slope_multiplied_by_negative_x1
    result = "y = " + (str(m) + "x" if m != 0 else "")
    if m != 0:
        X_intercept = (-1 * b) / m
    else:
        X_intercept = 'n/a'
    if m == 0:
        sign = ""
    elif b < 0:
        sign = " - "
    else:
        sign = " + "
    result = result + ("" if b == 0 else sign + str(abs(b)))
elif y1 != y2:
    result = "x = " + str(x1)
    X_intercept = x1
    b = 'n/a'
else:
    result = "(x, y) = (" + str(x1) + ", " + str(y1) + ')'
    X_intercept = 'n/a' if x1 != 0 else x1
    b = 'n/a' if y1 != 0 else y1
print(result)
print("X intercept: " + ("0.0" if X_intercept == 0 else str(X_intercept)))
print("Y intercept: " + str(b))
print("Distance between (x1,y1) and (x2,y2): " + str(d))

fig, ax = plt.subplots()
plt.plot(0, 0, color='k', marker='')  # just to make sure the plot contains 0,0
if X_intercept != 'n/a':
    plt.plot([X_intercept, x1], [0, y1], color='m', marker='o', linewidth=0.5)
    plt.plot([X_intercept, x2], [0, y2], color='m', marker='', linewidth=0.5)
if b != 'n/a':
    plt.plot([0, x1], [b, y1], color='m', marker='o', linewidth=0.5)
    plt.plot([0, x2], [b, y2], color='m', marker='', linewidth=0.5)
plt.plot([x1, x2], [y1, y2], color='c', linestyle='-', marker='o')
ax.spines['left'].set_position('zero')
ax.spines['bottom'].set_position('zero')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.grid()
plt.show()

在此处输入图像描述

这是一种画长线的方法。zorder=-1用于强制这条线位于其他线和点的后面。我们在最后(就在 之前plt.show)调用它,以便 matplotlib 可以自动计算限制以适应所有早期的东西。

xlims = plt.xlim()  # save the current limits
ylims = plt.ylim()
dx = (x2 - x1) * 100
dy = (y2 - y1) * 100
plt.plot([x1 - dx, x2 + dx], [y1 - dy, y2 + dy], color='k', linestyle='-', marker='', linewidth=0.5, zorder=-1)
plt.xlim(xlims)  # reapply the limits
plt.ylim(ylims)
于 2020-02-05T08:50:35.143 回答