在Python中使用pyside2实现Bezier样条

简而言之,这两天处理一些问题时需要使用一些样条函数,抱着站在牛顿肩膀上眺望的想法打开百度一顿搜索,可惜结果要么是代码参差不全,要么是积分下载,难以催动查克拉开动我的写轮眼。故老老实实根据定义和公式,使用pyside2自己写了一份Bezier样条生成程序。
关于Bezier样条的定义,鉴于可以在网上找到超过本人身高厚度的资料,故不在此贴出。
程序不带任何附加功能,单纯的根据控制点生成Bezier样条,如有错误,感谢指正。

效果图:


bezier.PNG

代码:

import sys

from PySide2 import QtCore, QtGui

from PySide2.QtCharts import QtCharts

from PySide2.QtWidgets import (QApplication, QWidget, QGraphicsScene,
    QGraphicsView, QGraphicsSimpleTextItem, QGraphicsItem)

class Vector2d(object):

    def __init__(self, x = 0, y = 0):

        self.X = x
        self.Y = y

    def x(self):

        return self.X

    def y(self):

        return self.Y

    def __add__(self, other):

        return Vector2d(self.X+ other.x(), self.Y+ other.y())

    def __sub__(self, other):

        return Vector2d(self.X- other.x(), self.Y- other.y())

    def __mul__(self, other):

        return Vector2d(self.X* other, self.Y* other)

    def __rmul_(self, other):

        return Vector2d(self.X* other, self.Y* other)

def GenerateBezierPoint(cpoints = list(), distance = 0.01):

    bezierPoints = list()
    t = 0.0
    count = len(cpoints)
    point = [Vector2d()] * (count-1)
    while(t <= 1):
        for i in range(0, count-1):
            point[i] = cpoints[i]*(1- t) + cpoints[i+1]*t
        length  = count-2
        while(length >= 1):
            for i in range(0, length):
                point[i] = point[i]*(1- t) + point[i+1]*t
            length -= 1
        bezierPoints.append( QtCore.QPointF( point[0].x(), point[0].y() ) )
        t += distance
    return bezierPoints

def convert(v2d):

    qpoint =list()
    for item in v2d:
        qpoint.append( QtCore.QPointF( item.x(), item.y() ) )

    return qpoint

def BezierPoints():

    return [ Vector2d(0, 0), Vector2d(30, 80), Vector2d(50, 10), Vector2d(80, 90), Vector2d(100, 5) ]

class MyBezier(QGraphicsView):

    def __init__(self, parent = None):

        super(MyBezier, self).__init__(parent)

        self.setWindowTitle('Bezier Spline')
        self.setScene(QGraphicsScene(self))

        self.setDragMode(QGraphicsView.NoDrag)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

        self.chart = QtCharts.QChart()
        self.chart.setMinimumSize(640, 480)
        self.chart.setTitle("Bezier Test")
        self.chart.legend().hide()
        self.series = QtCharts.QLineSeries()
        self.series.append( GenerateBezierPoint(BezierPoints(), 0.01) )
        self.cSeries = QtCharts.QLineSeries()
        self.cSeries.append( convert(BezierPoints()) )
        self.chart.addSeries(self.series)
        self.chart.addSeries(self.cSeries)
        self.chart.createDefaultAxes()
        self.scene().addItem(self.chart)
        self.setRenderHint(QtGui.QPainter.Antialiasing)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    v = MyBezier()
    v.show()
    sys.exit(app.exec_())
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。