0

I'm trying to find the points of intersection between the line passing through point V and conic. The conic graph is not solvable relative to y ( or x), so it was depicted using contour. Is there a method for finding the intersection points of contour graphs? enter image description here

Here is the code:

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')

I tried to do something like that:

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

or

# 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')

My last attempt:

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

  • You probably know this, but `print()` prints to stdout. Just saying... – Machta Aug 01 '19 at 16:01
  • i used print(c) to check what the operation intersection outputs – Sergey Kuznetsov Aug 01 '19 at 16:32
  • https://stackoverflow.com/questions/46909373/how-to-get-values-from-a-graph/46911822#46911822 – ImportanceOfBeingErnest Aug 01 '19 at 18:19
  • @ImportanceOfBeingErnest I tried to implement your method . Look like this: `code`m= conic-l3 z = find_roots(x,m) plt.plot(z, np.zeros(len(z)), marker="o", ls="", ms=4) `code` But the formula of a conic is an implicit function. – Sergey Kuznetsov Aug 02 '19 at 06:23
  • I guess you would want to [extract data from contour lines](https://stackoverflow.com/questions/5666056/matplotlib-extracting-data-from-contour-lines) first. – ImportanceOfBeingErnest Aug 02 '19 at 10:58
  • I tried and got the following this: `code` c = cnc.collections[0].get_paths()[0] v = c.vertices x1 = v[:,0] y1 = v[:,1] print(x1) print(y1) plt.plot(x1,y1,color='red') `code` – Sergey Kuznetsov Aug 02 '19 at 13:18
  • @ImportanceOfBeingErnest I also did the same for the line passing through point V , got the following : `vb1 = vb.collections[0].get_paths()[0] v1 = vb1.vertices x2 = v1[:,0] y2 = v1[:,1] print(x2) print(y2) plt.plot(x2,y2,color='green')` But I do not understand how you can determine the intersection point of these figures. I tried this: `s=y2-y1` , and got the error: ValueError: operands could not be broadcast together with shapes (2999,) (2381,). – Sergey Kuznetsov Aug 02 '19 at 15:52
  • Here's my last try; `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.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)` `plt.show()` – Sergey Kuznetsov Aug 02 '19 at 18:28
  • @ImportanceOfBeingErnest Of course I did that. – Sergey Kuznetsov Aug 02 '19 at 18:55

1 Answers1

0

It's a little more complicated. The problem is that (a) the points in the contour are not necessarily sorted and (b) the two contours do not have a common support.

So one would need to (a) sort the points along x, and (b) create an array of common values, on which to interpolate first.

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()

The point of intersection is the green dot.

enter image description here

Of course one needs to do the same for the other arm of the conic contour (cnc.collections[0].get_paths()[0]) if desired.

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712