如何找到和绘制轮廓形状的交点

时间:2019-08-01 15:32:25

标签: python-2.7 matplotlib contour

我试图找到通过V点的线与圆锥线之间的交点。圆锥曲线图相对于y(或x)不可解,因此使用等高线表示。有没有找到轮廓图交点的方法? enter image description here

代码如下:

import numpy as np
import matplotlib.pyplot as plt

p = (input("choose point P on axis OX: "))
print(p)
q = (input("choose point Q on axis OX: "))
print(q)
v = (input("choose point V on axis OX: "))
print(v)

k=3
X = np.arange(-50, 50, 0.05)
Y = k*X
plt.plot(X,Y)

plt.plot(0,0)
plt.scatter(0.0, 0.0, color='white', marker='o')
plt.text(0.0, 0.0, "O", horizontalalignment="center")

plt.plot(-v,0)
plt.scatter(-v, 0, color='red', marker='o')
plt.text(-v, 0.8, "V", horizontalalignment="center")

xmin= -10
xmax= 10
ymin= -10
ymax= 10
ax = plt.gca()
ax.get_xlim()
ax.set_xlim([xmin,xmax])
ax.set_ylim([ymin,ymax])
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('center')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

#Create random point B1
b1=4
plt.plot(0.0,b1)
plt.scatter(0.0, b1, color='blue', marker='o')
plt.text(0.8, b1, "B1", horizontalalignment="center")

x, y = np.meshgrid(X, X)

#Create VB1
l3 = b1*x+b1*v - v*y
vb = plt.contour(x,y, l3, [0], colors='k')
# l3 = b1*X/v + b1
# plt.plot(X,l3)

#Create conic
conic = x*x*b1*2*p*k-x*x*b1*2*q*k+x*x*k*k+y*y-b1*2*y+2*b1*q*x*y
cnc = plt.contour(x, y, (conic), [0], colors='k')

我试图做这样的事情:

  c = cnc.intersection(vb)
  print(c)

# https://stackoverflow.com/questions/28766692/intersection-of-two-graphs-in-python-find-the-x-value
    idx = np.argwhere(np.diff(np.sign(cnc - vb))).flatten()
    plt.plot(x[idx], y[idx], 'ro')

我最后一次尝试:

import numpy as np
import matplotlib.pyplot as plt
p,q,v,k,b=5,7,2,3,4
X = np.arange(-50, 50, 0.05)

plt.plot(-v,0)
plt.scatter(-v, 0, color='red', marker='o')
plt.text(-v, 0.8, "V", horizontalalignment="center")
xmin,xmax,ymin,ymax=-10,10,-10,10
ax = plt.gca()
ax.get_xlim()
ax.set_xlim([xmin,xmax])
ax.set_ylim([ymin,ymax])
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('center')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

plt.plot(0.0,b)
plt.scatter(0.0, 1, color='blue', marker='o')
x, y = np.meshgrid(X, X)

l = b*x+b*v-v*y
vb = plt.contour(x,y, l, [0], colors='k')

conic = x*x*b*2*p*k-x*x*b*2*q*k+x*x*k*k+y*y-b*2*y+2*b*q*x*y
cnc = plt.contour(x, y, (conic), [0], colors='k')

c = cnc.collections[0].get_paths()[1]
v = c.vertices
x1 = v[:,0]
y1 = v[:,1]
plt.plot(x1,y1)

vb1 = vb.collections[0].get_paths()[0]
v1 = vb1.vertices
x2 = v1[:,0]
y2 = v1[:,1]
plt.plot(x2,y2,color='red')

# def find_roots(x,y):
#      s = np.abs(np.diff(np.sign(y))).astype(bool)
#      return x[:-1][s] + np.diff(x)[s]/(np.abs(y[1:][s]/y[:-1][s])+1)
#
# z = find_roots(x1-x2,y1-y2)
# plt.plot(z, np.zeros(len(z)), marker="o", ls="", ms=4)
plt.show()

enter image description here

1 个答案:

答案 0 :(得分:0)

有点复杂。问题在于(a)轮廓中的点不一定要排序,并且(b)两个轮廓没有共同的支撑。

因此,您需要(a)对x上的点进行排序,并且(b)创建一个公共值数组,然后在该数组上首先进行插值。

import numpy as np
import matplotlib.pyplot as plt

p,q,v,k,b=5,7,2,3,4
X = np.arange(-50, 50, 0.05)

plt.plot(-v,0)
plt.scatter(-v, 0, color='red', marker='o')
plt.text(-v, 0.8, "V", horizontalalignment="center")
xmin,xmax,ymin,ymax=-10,10,-10,10
ax = plt.gca()
ax.get_xlim()
ax.set_xlim([xmin,xmax])
ax.set_ylim([ymin,ymax])
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('center')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)


x, y = np.meshgrid(X, X)

l = b*x+b*v-v*y
vb = plt.contour(x,y, l, [0], colors='red')

conic = x*x*b*2*p*k-x*x*b*2*q*k+x*x*k*k+y*y-b*2*y+2*b*q*x*y
cnc = plt.contour(x, y, (conic), [0], colors='blue')

c = cnc.collections[0].get_paths()[1]
v = c.vertices
x1 = np.sort(v[:,0])
y1 = v[np.argsort(v[:,0]),1]

vb1 = vb.collections[0].get_paths()[0]
v1 = vb1.vertices
x2 = np.sort(v1[:,0])
y2 = v1[np.argsort(v1[:,0]),1]


def find_roots(x,y):
    s = np.abs(np.diff(np.sign(y))).astype(bool)
    return x[:-1][s] + np.diff(x)[s]/(np.abs(y[1:][s]/y[:-1][s])+1)

x = np.linspace(max(x1.min(), x2.min()), min(x1.max(), x2.max()), 1000)

y1i = np.interp(x, x1, y1 )  # blue
y2i = np.interp(x, x2, y2 )  # red


x_intersect = find_roots(x,y2i-y1i)
y_intersect = np.interp(x_intersect, x, y2i)

plt.plot(x_intersect, y_intersect, marker="X", ms=5, color="limegreen")
plt.show()

交点是绿点。

enter image description here

当然,如果需要,圆锥形轮廓(cnc.collections[0].get_paths()[0])的另一只手臂也需要做同样的事情。