Python 考虑到每个点的位置和方向,如何连接点

Python 考虑到每个点的位置和方向,如何连接点,python,python-2.7,matplotlib,Python,Python 2.7,Matplotlib,在所附的图像中,我们可以看到一个点的运动的地面真实值(绿色)和估计值(红色)。带条形(=图案)的圆圈旁边的每个数字对应一个时间。现在所有的算法都已经开发出来了,我想通过将所有的模式连接在一起来提高可视化的质量,同时考虑到位置和方向(由条的方向定义)。我试图找到一种方法,但没有找到。有人有主意吗 仅供参考:我有坐标(x,y)和角度,必要时可以将其转换为导数 编辑:这里有一些关于我想将模式连接在一起的方式的说明 我想按照每个图案旁边的数字顺序连接所有图案 我想让曲线穿过每个图案的中心 我想我的曲线

在所附的图像中,我们可以看到一个点的运动的地面真实值(绿色)和估计值(红色)。带条形(=图案)的圆圈旁边的每个数字对应一个时间。现在所有的算法都已经开发出来了,我想通过将所有的模式连接在一起来提高可视化的质量,同时考虑到位置和方向(由条的方向定义)。我试图找到一种方法,但没有找到。有人有主意吗

仅供参考:我有坐标(x,y)和角度,必要时可以将其转换为导数

编辑:这里有一些关于我想将模式连接在一起的方式的说明

  • 我想按照每个图案旁边的数字顺序连接所有图案
  • 我想让曲线穿过每个图案的中心
  • 我想我的曲线在每一个模式的陡度是相同的画酒吧已经
总而言之:我正在寻找一种方法来绘制连接点的曲线,并在每个点处拟合所需的陡度


总结一下问题:您希望通过多个点插值平滑曲线。对于二维空间中的每个点,都有坐标以及定义曲线在此点的切线的角度

解决方案可能是使用三阶。该曲线将由4个点定义;两个端点(是绘图中的两个连续点)和两个中间点(定义曲线的方向)。Bézier曲线通常用于图形软件中,matplotlib也在内部使用Bézier曲线绘制路径

所以我们可以定义一条贝塞尔曲线,它有两个中间点,沿着切线,每个点的角度。 本质上没有关于切线上两个中间点应该位于何处的提示,因此我们可以选择距离两个端点的任意距离。这就是下面代码中所称的
r
。为该参数选择一个好的值
r
是获得平滑曲线的关键

import numpy as np
from scipy.special import binom
import matplotlib.pyplot as plt

bernstein = lambda n, k, t: binom(n,k)* t**k * (1.-t)**(n-k)

def bezier(points, num=200):
    N = len(points)
    t = np.linspace(0, 1, num=num)
    curve = np.zeros((num, 2))
    for i in range(N):
        curve += np.outer(bernstein(N - 1, i, t), points[i])
    return curve

class Segment():
    def __init__(self, p1, p2, angle1, angle2, **kw):
        self.p1 = p1; self.p2 = p2
        self.angle1 = angle1; self.angle2 = angle2
        self.numpoints = kw.get("numpoints", 100)
        method = kw.get("method", "const")
        if method=="const":
            self.r = kw.get("r", 1.)
        else:
            r = kw.get("r", 0.3)
            d = np.sqrt(np.sum((self.p2-self.p1)**2))
            self.r = r*d
        self.p = np.zeros((4,2))
        self.p[0,:] = self.p1[:]
        self.p[3,:] = self.p2[:]
        self.calc_intermediate_points(self.r)

    def calc_intermediate_points(self,r):
        self.p[1,:] = self.p1 + np.array([self.r*np.cos(self.angle1),
                                    self.r*np.sin(self.angle1)])
        self.p[2,:] = self.p2 + np.array([self.r*np.cos(self.angle2+np.pi),
                                    self.r*np.sin(self.angle2+np.pi)])
        self.curve = bezier(self.p,self.numpoints)


def get_curve(points, **kw):
    segments = []
    for i in range(len(points)-1):
        seg = Segment(points[i,:2], points[i+1,:2], points[i,2],points[i+1,2],**kw)
        segments.append(seg)
    curve = np.concatenate([s.curve for s in segments])
    return segments, curve


def plot_point(ax, xy, angle, r=0.3):
    ax.plot([xy[0]],[xy[1]], marker="o", ms=9, alpha=0.5, color="indigo")
    p = xy + np.array([r*np.cos(angle),r*np.sin(angle)])
    ax.plot([xy[0],p[0]], [xy[1],p[1]], color="limegreen")


if __name__ == "__main__":        
    #                   x    y    angle        
    points =np.array([[ 6.0, 0.5, 1.5],
                      [ 5.4, 1.2, 2.2],
                      [ 5.0, 1.7, 2.6],
                      [ 2.8, 2.4, 2.1],
                      [ 1.3, 3.2, 1.6],
                      [ 1.9, 3.9,-0.2],
                      [ 4.0, 3.0, 0.2],
                      [ 5.1, 3.7, 1.4]])

    fig, ax = plt.subplots()

    for point in points:
        plot_point(ax, point[:2],point[2], r=0.1)

    s1, c1 = get_curve(points, method="const", r=0.7)
    ax.plot(c1[:,0], c1[:,1], color="crimson", zorder=0, label="const 0.7 units")

    s2, c2 = get_curve(points, method="prop", r=0.3)
    ax.plot(c2[:,0], c2[:,1], color="gold", zorder=0, label="prop 30% of distance")
    plt.legend()
    plt.show()


在图中,对上述两种情况进行了比较。其中一个
r
为常数
0.7
单位,另一个
r
为两点之间距离的30%

您需要更详细地解释“将所有模式连接在一起”。否则,没有人能理解你想做什么。此外,实现这一目标的问题到底是什么?你尝试过什么,在多大程度上没有奏效。如果你不说出你有什么问题,这个问题可能太广泛而无法回答。谢谢你的留言!我编辑了它。我希望这将有助于理解我想要连接模式的方式。我的主要问题是找不到任何允许我做我想做的事情的函数。我希望已经尝试过做同样事情的人能给我一个关于如何完成这样一项任务的提示。我不认为你会找到一个预定义的函数来做你想做的事情,因为问题是二维的(你实际上有二维梯度,而不是一维导数),因此没有连接点的唯一解决方案。如果这是一个1D问题,像
scipy.interpolate.KroghInterpolator
这样的工具可以帮助您。但是,在这种情况下,它将失败。请您发布用于生成图片的代码(不需要背景)以及用于生成5分的数据,好吗?@Thomas如果您想进行实验,可以从下面我的答案中获取数据。如果有人对如何“拟合”贝塞尔曲线或采用不同的方法有想法,那肯定会很有趣。这正是我想要的。非常感谢您的详细解释!这很有帮助!伟大的只需注意以下几点:问题本身的质量相当低,通常无法回答或关闭(请参阅);我在这里提供答案的原因是我自己觉得深入研究很有趣,因为我以前从未做过这样的事情。但我想你不能指望下次你问问题时会发生这种情况。