Search code examples
pythonopenglpyqtpyqtgraph

PyQtGraph & OpenGL: How to create a sphere between two coordinates?


Is it possible to create a sphere between two coordinates using PyQtGraph and OpenGL? In my sample code I have made a sphere, but the position and size is only determined by "rows" and "columns". I would like to connect the end points of the sphere between point1 and point2. Can you help me?

enter image description here

from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import pyqtgraph.opengl as gl
import numpy as np
import sys

app = QtGui.QApplication([])
w = gl.GLViewWidget()
w.show()
w.setCameraPosition(distance=15, azimuth=-90)

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

# coordinates
point1 = np.array([0, 0, 0])
point2 = np.array([0, 5, 0])

md = gl.MeshData.sphere(rows=10, cols=20)

m1 = gl.GLMeshItem(meshdata=md, smooth=True, color=(1, 0, 0, 0.2), shader='balloon', glOptions='additive')
m1.scale(1, 1, 2)
w.addItem(m1)


if __name__ == '__main__':

    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

Solution

  • The sphere() method returns a data associated with a sphere of a certain radius (by default 1) and centered on (0, 0, 0), so using the information of point1 and point2 you can obtain the radius and the center, to establish the center has to move the item using the translate() method:

    from pyqtgraph.Qt import QtCore, QtGui
    import pyqtgraph as pg
    import pyqtgraph.opengl as gl
    import numpy as np
    import sys
    
    app = QtGui.QApplication([])
    w = gl.GLViewWidget()
    w.show()
    w.setCameraPosition(distance=15, azimuth=-90)
    
    g = gl.GLGridItem()
    w.addItem(g)
    
    # coordinates
    point1 = np.array([0, 0, 0])
    point2 = np.array([0, 5, 0])
    
    center = (point1 + point2) / 2
    radius = np.linalg.norm(point2 - point1) / 2
    
    md = gl.MeshData.sphere(rows=10, cols=20, radius=radius)
    
    m1 = gl.GLMeshItem(
        meshdata=md,
        smooth=True,
        color=(1, 0, 0, 0.2),
        shader="balloon",
        glOptions="additive",
    )
    m1.translate(*center)
    
    w.addItem(m1)
    
    
    
    if __name__ == "__main__":
    
        if (sys.flags.interactive != 1) or not hasattr(QtCore, "PYQT_VERSION"):
            QtGui.QApplication.instance().exec_()