简而言之,这两天处理一些问题时需要使用一些样条函数,抱着站在牛顿肩膀上眺望的想法打开百度一顿搜索,可惜结果要么是代码参差不全,要么是积分下载,难以催动查克拉开动我的写轮眼。故老老实实根据定义和公式,使用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_())