对中国人的中心投射

时间:2016-03-01 18:40:28

标签: python numpy line-intersection

我有以下问题。给定2D空间中的两个数据集。两个数据集是来自示例中给出的中心点的2D测量点(0,0)。我需要使用点之间的线性插值将第一个数据集(x1,y1)的点集中在由第二个数据集定义的线段上。

import numpy as np
import matplotlib.pyplot as plt

x1 = np.arange(-50, 50, 1)
y1 = 50+np.random.rand(100)*5

x2 = np.arange(-20, 30, 50.0/320)
y2 = 30+np.random.rand(320)*0.5

plt.plot(x1, y1, '*',   
         x2, y2, 'x',
         0.0, 0.0, 'o') 

plt.show()

example profiles

我已经为连接set1与源点和set2的线段的所有线实现了经典线交叉计算。不幸的是,nasted for loop效率不高。

有没有办法让这个算法运行得更快?也许是矢量化实现?

有什么想法吗?提前谢谢。

行。让我重新定义问题。

我有以下代码:

import numpy as np
import matplotlib.pyplot as plt
import time

set1 = np.zeros((100, 2))
set2 = np.zeros((320, 2))
set3 = np.zeros((100, 2))

# p1
set1[:, 0] = np.arange(-50, 50, 1)
set1[:, 1] = 50+np.random.binomial(5, 0.4, size=100)

# p2 and p3
set2[:, 0] = np.arange(-20, 50, 70.0/320)
set2[:, 1] = 30+np.random.binomial(8, 0.25, size=320)

# p0
sp = np.array([0.0, 0.0])

tstamp = time.time()

# building line direction vectors 
s1 = set1                   # set 1 is already the direction vector as sp=[0,0]
s2 = set2[1:] - set2[0:-1]  # set 2 direction vector (p3-p2)

projected_profile = np.zeros((100, 2))

# project set1 on set2
for i in range(np.size(s1)/2):
    intersect_points = np.zeros((100, 2))
    ts = np.zeros(100)
    ind1 = 0
    for j in range(np.size(s2)/2):
        # calculate line intersection
        div = s1[i, 0] * s2[j, 1] - s2[j, 0] * s1[i, 1]
        s = (s1[i, 1] * set2[j, 0] - s1[i, 0] * set2[j, 1]) / div
        t = (s2[j, 1] * set2[j, 0] - s2[j, 0] * set2[j, 1]) / div

        # check wether we are still on the line segments
        if (s>=0 and s<=1 and t>=0 and t <=1):
            intersect_points[ind1, :] = t * s1[i]
            ts[ind1] = t
            ind1 += 1

    # take the intersection with maximal distance from source point (sp)
    if ts.sum()>0:
        projected_profile[i, :] = intersect_points[np.argmax(ts), :]

print time.time()-tstamp

plt.plot(set1[:, 0], set1[:, 1], '*',
         set2[:, 0], set2[:, 1], '-',
         projected_profile[:, 0], projected_profile[:, 1], 'x',
         sp[0], sp[1], 'o')

plt.show()

enter image description here

代码中心投影曲线上set1中的点,该点由set2中的点使用线性插值定义。

1 个答案:

答案 0 :(得分:0)

我设法解决了我的问题。如果有人将来需要它,这是解决方案。它运行得更好:

import numpy as np
import matplotlib.pyplot as plt
import time

set1 = np.zeros((100, 2))
set2 = np.zeros((320, 2))
set3 = np.zeros((100, 2))

# p1
set1[:, 0] = np.arange(-50, 50, 1)
set1[:, 1] = 50+np.random.binomial(5, 0.4, size=100)

# p2 and p3
set2[:, 0] = np.arange(-20, 50, 70.0/320)
set2[:, 1] = 30+np.random.binomial(8, 0.25, size=320)

# p0
sp = np.array([0.0, 0.0])

tstamp = time.time()

# building line direction vectors 
s1 = set1                   # set 1 is already the direction vector as sp=[0,0]
s2 = set2[1:] - set2[0:-1]  # set 2 direction vector (p3-p2)

num_master = np.size(s1, axis=0)
num_measure = np.size(s2, axis=0)

# calculate intersection
div = np.transpose(np.repeat([s1[:, 0]], num_measure, axis=0)) * s2[:, 1] - \
      np.transpose(np.transpose(np.repeat([s2[:, 0]], num_master, axis=0)) * s1[:, 1])

s = np.transpose(np.repeat([s1[:, 1]], num_measure, axis=0)) * set2[:-1, 0] - \
    np.transpose(np.repeat([s1[:, 0]], num_measure, axis=0)) * set2[:-1, 1]
s = s / div

t = s2[:, 1] * set2[:-1, 0] - s2[:, 0] * set2[:-1, 1]
t = t / div

# get results by masking invalid results
mask = np.bitwise_and(np.bitwise_and(s>=0, s<=1),
                      np.bitwise_and(t>=0, t<=1))

# mask indices
ind1 = mask.sum(1)>0
t[np.invert(mask)] = 0
ind2 = np.argmax(t[ind1], axis=1)

# calculate result
projected_profile = s1[ind1] * np.transpose(np.repeat([t[ind1, ind2]], 2, axis=0))

print time.time()-tstamp

plt.plot(set1[:, 0], set1[:, 1], '*',
         set2[:, 0], set2[:, 1], '-',
         projected_profile[:, 0], projected_profile[:, 1], 'x',
         sp[0], sp[1], 'o')

plt.show()