Python 如何使用pyqtgraph和OpenGL在两个更新的3D点之间连接椭圆形或圆柱形形状?

Python 如何使用pyqtgraph和OpenGL在两个更新的3D点之间连接椭圆形或圆柱形形状?,python,opengl,pyqt,pyqtgraph,Python,Opengl,Pyqt,Pyqtgraph,我想使用pyqtgraph和OpenGL在3D空间中的两个更新点之间形成一个形状。目前,我只发现在两点之间连接顶点和平面是可能的。然而,我希望在点之间连接一个椭圆形或圆柱体,但我似乎找不到一种方法来使用积分球体和圆柱体,而不跳进复杂的数学、旋转矩阵和三角 是否有更简单的方法,类似于GLLinePlotItem或GLMeshItem 说明我现在拥有的以及我想拥有的: 示例代码: from pyqtgraph.Qt import QtCore, QtGui import pyqtgraph as

我想使用pyqtgraph和OpenGL在3D空间中的两个更新点之间形成一个形状。目前,我只发现在两点之间连接顶点和平面是可能的。然而,我希望在点之间连接一个椭圆形或圆柱体,但我似乎找不到一种方法来使用积分球体和圆柱体,而不跳进复杂的数学、旋转矩阵和三角

是否有更简单的方法,类似于GLLinePlotItem或GLMeshItem

说明我现在拥有的以及我想拥有的:

示例代码:

from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import pyqtgraph.opengl as gl
import numpy as np
import sys
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QMainWindow, QApplication
from random import randint

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        w = gl.GLViewWidget()
        w.show()
        w.setCameraPosition(distance=15, azimuth=-90)

        self.timer = QTimer()
        self.timer.start(1000)
        self.timer.timeout.connect(self.start)

        g = gl.GLGridItem()
        g.scale(2, 2, 1)
        w.addItem(g)


        self.md = gl.MeshData.sphere(rows=10, cols=20)
        self.m1 = gl.GLMeshItem(meshdata=self.md,
                                smooth=True,
                                color=(1, 0, 0, 0.2),
                                shader="balloon",
                                glOptions="additive")
        w.addItem(self.m1)

        self.lineMesh = gl.GLLinePlotItem(width=1, antialias=False)
        w.addItem(self.lineMesh)


    def start(self):
        # coordinates

        point1 = np.array([randint(0,25), randint(0,25), 0])
        point2 = np.array([randint(0,25), randint(0,25), 20])

        line = np.array([point1, point2])
        self.lineMesh.setData(pos=line)

        length = (((point2[0] - point1[0]) ** 2 + (point2[1] - point1[1]) ** 2 + (
                point2[2] - point1[2]) ** 2) ** 0.5)*0.5

        center = (point1 + point2) / 2
        #radius = np.linalg.norm(point2 - point1) / 2


        self.md = gl.MeshData.sphere(rows=10, cols=20, radius=[1])
        self.m1.setMeshData(meshdata=self.md)

        self.m1.resetTransform()
        self.m1.scale(1, 1, length)
        self.m1.translate(*center)



if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MainWindow()
    ex.show()
    sys.exit(app.exec_())

我不认为你可以避免在这里做一点数学,但三角也不太糟糕:

        v = point2 - point1
        theta = np.arctan2(v[1], v[0])
        phi = np.arctan2(np.linalg.norm(v[:2]), v[2])

        tr = pg.Transform3D()
        tr.translate(*point1)
        tr.rotate(theta * 180 / np.pi, 0, 0, 1)
        tr.rotate(phi * 180 / np.pi, 0, 1, 0)
        tr.scale(1, 1, np.linalg.norm(v) / 2)
        tr.translate(0, 0, 1)

        self.m1.setTransform(tr)
如果你更喜欢线性代数而不是三角,那也不算太糟,尽管有点冗长:

        # pick 4 points on the untransformed sphere
        a = np.array([
            [0., 0., -1.],
            [0., 0., 1.],
            [1., 0., -1.],
            [0., 1., -1.],
        ])

        # and 4 corresponding points on the transformed sphere
        v1 = np.cross(point1-point2, [0., 0., 1.])
        v2 = np.cross(point1-point2, v1)
        b = np.array([
            point1,
            point2,
            point1 + v1 / np.linalg.norm(v1),
            point1 + v2 / np.linalg.norm(v2),
        ])

        # solve the transform mapping from a to b
        tr = pg.solve3DTransform(a, b)

        # make this transform work in opengl's homogeneous coordinate system
        tr[3,3] = 1

        self.m1.setTransform(tr)

非常感谢你,卢克。它工作得很好。我使用了第一个解决方案,因为我最了解这个解决方案。你能帮我找到最后一个旋转“psi”吗?你是说围绕连接两个端点的轴旋转吗?我不确定你想用什么标准,因为这需要第三个参考点……是的,没错。然而,你是对的。实际上我有第三个参考点,用它我可以计算出角度。谢谢你的指导。