Plot a Prism in MatplotLib (Python) with "sympy.vector.point.Point"-class

Viewed 236

I would like to create a 3D-Plot of a prism (or to be less specific: a polyhedron) with the matplotlib. I create the vertices of the prism with a point and some vectors, so that I can control the creation of the prism (like: the base area should be a triangle (or a rectangle or a parallelogram) or the the base area should be parallel to the x- and y-axis etc.).

I use the sympy vector library and the vertices of the prism are of the type 'sympy.vector.point.Point' and are stored in a dictionary (so that I can adress the points via the given name of the point).

I got an error, when I'm even trying to scatter-plot the vertices. In other examples they used numpy, but this didn't worked in my example ether. Beside this matplotlib should be able to handle sympy-coordinates, shouldn't it?

Thanks in advance for any help!

from sympy.vector import CoordSys3D

class Prism():
    def __init__(self):
        self.punkte = {}
        self.ks = CoordSys3D("N")
        # here happens some magic to create the vertices as I wish 
        # (mostly random, but with some given options)
        # to make the code example much shorter, I just create a given cuboid
        AB = 5*self.ks.i
        AD = 10*self.ks.j
        AE = 3*self.ks.k
        self.add_point(self.ks.origin, AB.zero)         # point A
        self.add_point(self.punkte.get("A"), AB)        # point B
        self.add_point(self.punkte.get("B"), AD)        # point C
        self.add_point(self.punkte.get("A"), AD)        # point D etc.
        self.add_point(self.punkte.get("A"), AE)
        self.add_point(self.punkte.get("B"), AE)
        self.add_point(self.punkte.get("C"), AE)
        self.add_point(self.punkte.get("D"), AE)

    def add_point(self, ausgangspunkt, vektor):
        alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
        name = alphabet[len(self.punkte)]
        neuer_punkt = ausgangspunkt.locate_new(name, vektor)
        self.punkte.update({name: neuer_punkt})

    def plot(self):
        from matplotlib import pyplot as plt
        from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')
        x, y, z = [], [], []
        for punkt in self.punkte.values():
            x.append(punkt.express_coordinates(self.ks)[0])
            y.append(punkt.express_coordinates(self.ks)[1])
            z.append(punkt.express_coordinates(self.ks)[2])
        ax.scatter3D(x, y, z)
        plt.show()

testprism = Prism()
testprism.plot()
0 Answers
Related