How to find the intersection points of a straight line and a curve-like set of two dimensional points?

人盡茶涼 提交于 2020-07-07 14:26:08

问题


Suppose we have:

  1. A curve described by a two-dimensional dataset that describes approximately a high order polynomial curve.
  2. A line defined by two points.

This is a sample image:

Supposing the line and the curve intercept each other, how could I find the intersection point between the line and the dataset?


回答1:


As per my comment above

import numpy as np

A = np.random.random((20, 2))
A[:,0] = np.arange(20)
A[:,1] = A[:,1] * (7.5 + A[:,0]) # some kind of wiggly line
p0 = [-1.0,-6.5] # point 0
p1 = [22.0, 20.0] # point 1

b = (p1[1] - p0[1]) / (p1[0] - p0[0]) # gradient
a = p0[1] - b * p0[0] # intercept
B = (a + A[:,0] * b) - A[:,1] # distance of y value from line
ix = np.where(B[1:] * B[:-1] < 0)[0] # index of points where the next point is on the other side of the line
d_ratio = B[ix] / (B[ix] - B[ix + 1]) # similar triangles work out crossing points
cross_points = np.zeros((len(ix), 2)) # empty array for crossing points
cross_points[:,0] = A[ix,0] + d_ratio * (A[ix+1,0] - A[ix,0]) # x crossings
cross_points[:,1] = A[ix,1] + d_ratio * (A[ix+1,1] - A[ix,1]) # y crossings

print(ix, B, A, cross_points)



回答2:


Since the curve data appears to be dense and not scattered (as for example the result of a numerically solved differential equation), interpolating or approximating the whole curve dataset is overkill. In the following, I assume that the points of the dataset are ordered along the curve (as if they were the result of sampling a parametric curve).

  1. First, do a coordiante transformation A(x,y) with a translation an a rotation such that the red line matches the x axis.

  2. Intersect the transformed curve with the x axis, i.e. take all points from the curve dataset with a small absolute value of the y-coordinate (and remember their indices in the dataset). Try y < 0.05 for the depicted curve.

  3. Use the indices from the points selected in 2. to detect ranges of adjacent curve points, each range resembling a small bit of the curve.

Sloppy version

  1. For each range, take the average value x_mean of the x-coordinates. The inverse coordinate transformation A_inv(x_mean, 0) will give you an approximation of the intersection point of that range. Depending on your use case and the complexity of potential curves, the approximation may already be good enough.

Sophisticated version

  1. Approximate each range with a line or a polynomial curve of low degree <= 4.

    • Map the indices of the the range into the unit interval, such that e.g. [103, 104, 105, 106, 107] becomes [0.0, 0.25, 0.5, 0.75, 1.0]
    • Split the range data into a range of x and y coordinates.
    • Approximate the x and y data separately as 1D-function to express the curve data as a parametric function (x(t), y(t)) with t from [0, 1] (using the mapped indices from above as interpolation knots).
    • Use a polynomial solver to solve y(t) == 0.
    • For each zero t_zero inside [0, 1], evaluate the approximation funtcion x(t) at t_zero. The inverse coordinate transformation A_inv(x(t_zero), 0) gives you an approximation of the intersection point at t_zero in your original coordinates.

If you can confirm, that this solution may suit your problem, I may provide an according numpy example.



来源:https://stackoverflow.com/questions/37951631/how-to-find-the-intersection-points-of-a-straight-line-and-a-curve-like-set-of-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!