def plotlist_xyz(self, face: Face):
        """Return a list of lists with the xyz coordinates of each vertex."""
        # If object has no parent, return plot list in terms of global frame:
        
        plotlist_xyz = []
        
        for vertex in face.vertices():
            plotlist_xyz.append(list(self.vertex_xyz_global(vertex)))

        return plotlist_xyz
 def face_centroid(self, face: Face):
     """Find the vertex centroid of the face."""
     
     xc = 0
     yc = 0
     zc = 0
     
     for vertex in face.vertices():
         (dx, dy, dz) = self.vertex_xyz_global(vertex)
         xc += 0.25*dx
         yc += 0.25*dy
         zc += 0.25*dz
 
     return np.array([xc, yc, zc])
def plot_face(axes,
              face: Face,
              fill=0,
              alpha=0.2,
              linecolour='black',
              linealpha=1,
              illumination=False,
              ill_value=0):
    """ Plots an individual Face object. Check source code for kwargs.
    """
    (xlist, ylist, zlist) = face.plotlist()

    # Plot individual vertices:
    axes.scatter(xlist, ylist, zlist, c=linecolour, s=10)

    # Plot edges that connect vertices:
    for i in range(-1, len(xlist) - 1):
        axes.plot3D([xlist[i], xlist[i + 1]], [ylist[i], ylist[i + 1]],
                    [zlist[i], zlist[i + 1]],
                    linecolour,
                    alpha=linealpha,
                    lw=2)

    # Plot the face surface:
    if fill == 1:

        fs = mp3d.art3d.Poly3DCollection([face.plotlist2()], linewidth=0)
        # If illumination functionality is turned on, face is coloured
        # based on its illumination value.
        if illumination == True:
            # No illumination: rgb = [0.1, 0.1, 0.1] (dark gray)
            # Total illumination: [1, 1, 1] (white)
            value = round(0.1 + 0.9 / 1.6 * ill_value, 2)
            fs.set_facecolor((value, value, value, alpha))
        else:
            fs.set_facecolor((0.1, 0.1, 0.1, alpha))
        axes.add_collection3d(fs)
 def plotlist(self, face: Face):
     """Return three lists with the x, y, and z-components of all four
        vertices in the face."""
     
     xlist = []
     ylist = []
     zlist = []
 
     for vertex in face.vertices():
         xg, yg, zg = self.vertex_xyz_global(vertex)
         xlist.append(xg)
         ylist.append(yg)
         zlist.append(zg)
     
     return xlist, ylist, zlist
 def project_face(self, face: Face, plane='xy', new_frame=None):
     """Project a copy of the face onto a plane that is spanned by two
         axes. The projection is orthographic. Coordinates will be in terms
         of the GLOBAL frame.
         
         TODO: A "new_frame" can be specified, which will make the 
         projection elements children of this frame. Otherwise, the 
         elements will be children of the global coordinate frame.
         
         TODO: Generalize this function for arbitrary projection plane. 
         """
     # Eliminate minus sign in front of the plane:    
     if plane[0] == '-':
         plane = plane[1:]
     
     pj_xyz = []
     
     for vertex in [face.p1, face.p2, face.p3, face.p4]:
         
         global_coords = self.vertex_xyz_global(vertex)
         
         if plane == 'xy':
             pj_x = global_coords[0]
             pj_y = global_coords[1]
             pj_z = 0
         elif plane == 'xz':
             pj_x = global_coords[0]
             pj_y = 0
             pj_z = global_coords[2]
         elif plane == 'yz':
             pj_x = 0
             pj_y = global_coords[1]
             pj_z = global_coords[2]
         else:
             raise ValueError("No valid projection plane given to "
                               "projection method! "
                               "Valid options: 'xy', 'xz', 'yz'")
         pj_xyz.append(Vertex([pj_x, pj_y, pj_z], parenttype="face"))
     
     # Create the projected face using the projected vertices.
     if not new_frame: 
         pj = Face(pj_xyz[0], pj_xyz[1], pj_xyz[2], pj_xyz[3],
                   parenttype="global")
     else:
         raise TypeError("new_frame functionality is not yet implemented.")
     return pj
 def remove_face(self, face: Face):
     self.faces.remove(face)
     face.set_parenttype="global"
 def add_face(self, face: Face):
     self.faces.append(face)
     face.set_parenttype="frame"
    angle_step = d2r(360 / steps)

    frame1 = Frame()
    frame1.translate(0.5, 0.5, 0.5)
    frame1.rotate(0, 0, d2r(1 * 360 / 12))

    p1 = Vertex(-0.05, -0.05, -0.1, frame1)
    p2 = Vertex(-0.05, -0.05, 0.1, frame1)
    p3 = Vertex(0.05, -0.05, 0.1, frame1)
    p4 = Vertex(0.05, -0.05, -0.1, frame1)
    p5 = Vertex(-0.05, 0.05, -0.1, frame1)
    p6 = Vertex(-0.05, 0.05, 0.1, frame1)
    p7 = Vertex(0.05, 0.05, 0.1, frame1)
    p8 = Vertex(0.05, 0.05, -0.1, frame1)

    fA = Face(p4, p3, p2, p1, frame1)
    fB = Face(p2, p3, p7, p6, frame1)
    fC = Face(p3, p4, p8, p7, frame1)
    fD = Face(p4, p1, p5, p8, frame1)
    fE = Face(p1, p2, p6, p5, frame1)
    fF = Face(p5, p6, p7, p8, frame1)

    cubesat = Geometry(frame1)
    cubesat.add_faces([fA, fB, fC, fD, fE, fF])

    def update(i):

        # Transforming frame1
        cubesat.rotate(angle_step, 0, 0, cor=cubesat.make_cuboid_centroid())

        projection_frame = Frame()
Beispiel #9
0
    ax.view_init(elev=20, azim=-60)

    steps = 24
    angle_step = d2r(360 / steps)

    p0 = Vertex([0.5, 0.5, 0.5])
    p1 = Vertex([-0.05, -0.05, -0.1])
    p2 = Vertex([-0.05, -0.05, 0.1])
    p3 = Vertex([0.05, -0.05, 0.1])
    p4 = Vertex([0.05, -0.05, -0.1])
    p5 = Vertex([-0.05, 0.05, -0.1])
    p6 = Vertex([-0.05, 0.05, 0.1])
    p7 = Vertex([0.05, 0.05, 0.1])
    p8 = Vertex([0.05, 0.05, -0.1])

    fA = Face(p4, p3, p2, p1)
    fB = Face(p2, p3, p7, p6)
    fC = Face(p3, p4, p8, p7)
    fD = Face(p4, p1, p5, p8)
    fE = Face(p1, p2, p6, p5)
    fF = Face(p5, p6, p7, p8)

    cubesat = Geometry([fA, fB, fC, fD, fE, fF])

    frame1 = Frame()
    frame1.add_geometry(cubesat)
    frame1.translate(0.5, 0.5, 0.5)
    frame1.rotate(0, 0, d2r(1 * 360 / 12))

    # cubesat.rotate(d2r(-45),0,0,cor=list(cubesat.find_cuboid_centroid()))
Beispiel #10
0
from cp_frame import Frame
from cp_utilities import d2r  #, r2d
from cp_plotting import plot_global_tripod, plot_frame, \
    plot_vertex, plot_face, plot_geometry_perpendiculars, plot_illumination

p0 = Vertex([0.5, 0.5, 0.5])
p1 = Vertex([-0.05, -0.05, -0.1])
p2 = Vertex([-0.05, -0.05, 0.1])
p3 = Vertex([0.05, -0.05, 0.1])
p4 = Vertex([0.05, -0.05, -0.1])
p5 = Vertex([-0.05, 0.05, -0.1])
p6 = Vertex([-0.05, 0.05, 0.1])
p7 = Vertex([0.05, 0.05, 0.1])
p8 = Vertex([0.05, 0.05, -0.1])

fA = Face(p4, p3, p2, p1)
fB = Face(p2, p3, p7, p6)
fC = Face(p3, p4, p8, p7)
fD = Face(p4, p1, p5, p8)
fE = Face(p1, p2, p6, p5)
fF = Face(p5, p6, p7, p8)

cubesat = Geometry([fA, fB, fC, fD, fE, fF])

frame1 = Frame()
frame1.add_geometry(cubesat)
frame1.translate(0.5, 0.5, 0.5)
frame1.rotate(0, 0, d2r(1 * 360 / 12))

cubesat.rotate(d2r(-45), 0, 0, cor=list(cubesat.find_cuboid_centroid()))
 def add_face(self, face: Face):
     """Add a singular face to the geometry."""
     self.faces.append(face)
     face.set_parenttype("geometry")
                                     #         | 
 p1 = Vertex([-0.05, -0.05, -0.1])   #      2 ___ 6
 p2 = Vertex([-0.05, -0.05,  0.1])   #       |\3__\7 
 p3 = Vertex([ 0.05, -0.05,  0.1])   #       | |  |         Y
 p4 = Vertex([ 0.05, -0.05, -0.1])   #      1| | 5|  -------->
 p5 = Vertex([-0.05,  0.05, -0.1])   #        \|__|
 p6 = Vertex([-0.05,  0.05,  0.1])   #        4    8  
 p7 = Vertex([ 0.05,  0.05,  0.1])   #            \
 p8 = Vertex([ 0.05,  0.05, -0.1])   #             v X
 
 # Assembling the side panels of the Cubesat. Note that the order in which
 #   the points is specified DOES matter! (see definition of Face class)
 
                             #         ^ Z
                             #         | 
 fA = Face(p4, p3, p2, p1)   #     E  ___  
 fB = Face(p2, p3, p7, p6)   #       |\ B_\  
 fC = Face(p3, p4, p8, p7)   #     A | |  | F        Y
 fD = Face(p4, p1, p5, p8)   #       | | C|  -------->
 fE = Face(p1, p2, p6, p5)   #        \|__|
 fF = Face(p5, p6, p7, p8)   #          D       
                             #            \
                             #             v X
 
 # Assembling a Geometry instance named 'cubesat', and add all the faces
 #   we just defined to the geometry.
 cubesat = Geometry([fA, fB, fC, fD, fE, fF])
 
 # Define a reference frame which will be attached to the centre of gravity
 #   of the CubeSat. If you move/rotate this frame, the 'cubesat' 
 #   Geometry will move/rotate along with it (if it is attached of course).
frame2 = Frame()

# p1 = Vertex(0,0,0,frame1)
# p2 = Vertex(1,0,0)
# p3 = Vertex(1,1,0)
# p4 = Vertex(0,1,0)
# p5 = Vertex(0,1,1)
# p6 = Vertex(0,0,1)

# f1 = Face(p1, p2, p3, p4, frame1)
# f2 = Face(p1, p4, p5, p6, frame1)

frame1.readout()

f1 = Face(Vertex(0, 0, 0), Vertex(1, 0, 0), Vertex(1, 1, 0), Vertex(0, 1, 0),
          frame1)

frame1.readout()

del (f1)

frame1.readout()

#%% ==== Plotting ====

# Toggle plotting functionality:
if False:

    # Setting up the plot:
    fig = plt.figure(figsize=(8, 8))
    ax = mp3d.Axes3D(fig)
    ax.view_init(elev=20, azim=-50)

    steps = 64
    angle_step = d2r(360 / steps)

    p0 = Vertex([0.5, 0.5, 0.5])
    p1 = Vertex([-0.05, -0.05, -0.1])
    p2 = Vertex([-0.05, -0.05, 0.1])
    p3 = Vertex([0.05, -0.05, 0.1])
    p4 = Vertex([0.05, -0.05, -0.1])
    p5 = Vertex([-0.05, 0.05, -0.1])
    p6 = Vertex([-0.05, 0.05, 0.1])
    p7 = Vertex([0.05, 0.05, 0.1])
    p8 = Vertex([0.05, 0.05, -0.1])

    fA = Face(p4, p3, p2, p1)
    fB = Face(p2, p3, p7, p6)
    fC = Face(p3, p4, p8, p7)
    fD = Face(p4, p1, p5, p8)
    fE = Face(p1, p2, p6, p5)
    fF = Face(p5, p6, p7, p8)

    cubesat = Geometry([fA, fB, fC, fD, fE, fF])

    frame1 = Frame()
    frame1.add_geometry(cubesat)
    frame1.translate(0.3, 0.3, 0.25)

    frame1.rotate(0, 0, d2r(1.5 * 360 / 12))

    # DO A BARN DOOR!
def plot_face(
    axes: plt.matplotlib.axes,
    face: Face,
    plotlist: list = None,

    # Face plotting properties:
    linefill=True,  # If False, does not plot face lines
    linecolour="#000",  # Colour of face lines
    linewidth=2,  # Thickness of face lines
    linealpha=1,  # Opacity of face lines
    facefill=True,  # If False, does not shade the face area
    facecolour="#555",  # Colour of the face area shading
    facealpha=1,  # Opacity of the face area shading

    # Vertex plotting properties:
    vertexfill=True,  # If False, vertex will not be plotted
    vertexcolour="#000",  # Specifies the vertex colour
    vertexsize=10,  # Size of the plotted vertex
    vertexalpha=1,  # Opacity of the plotted vertex

    # Illumination:
    illumination=False,  # If True, plots illumination intensity
    ill_value=0  # Used to plot illumination intensity
):
    """ Plots an individual Face object. Check source code for kwargs.
    """
    def plotlist2plotlist_xyz(plotlist: tuple):
        """Return a list of lists with the xyz coordinates of each vertex."""
        # If object has no parent, return plot list in terms of global frame:

        p1_xyz = []
        p2_xyz = []
        p3_xyz = []
        p4_xyz = []

        for coordinate_row in plotlist:
            p1_xyz.append(coordinate_row[0])
            p2_xyz.append(coordinate_row[1])
            p3_xyz.append(coordinate_row[2])
            p4_xyz.append(coordinate_row[3])

        return [p1_xyz, p2_xyz, p3_xyz, p4_xyz]

    # Situations:
    # 1. Face is an orphan (parent == "global") and so it has to use
    #    local coordinates only
    # 2. Face is part of a geometry, which we will assume has a frame underlying
    #    it

    # print("[DEBUG] Plotting {}".format(face))

    # Case 1: Face is an orphan:
    if face.parenttype == "global":
        (xlist, ylist, zlist) = face.plotlist_local()

        # Plot individual vertices:
        if vertexfill:
            for vertex in face.vertices():
                plot_vertex(axes, vertex)

        # Plot edges that connect vertices:
        for i in range(-1, len(xlist) - 1):
            axes.plot3D([xlist[i], xlist[i + 1]], [ylist[i], ylist[i + 1]],
                        [zlist[i], zlist[i + 1]],
                        linecolour,
                        alpha=linealpha,
                        lw=linewidth)

        # Plot the face surface:
        if facefill:
            plotlist_xyz = plotlist2plotlist_xyz(face.plotlist_local())
            fs = mp3d.art3d.Poly3DCollection([plotlist_xyz], linewidth=0)

            (nR, nG, nB) = hex2nRGB(facecolour)
            fs.set_facecolor((nR, nG, nB, facealpha))
            axes.add_collection3d(fs)

    # Case 2: Face is in a frame
    else:
        (xlist, ylist, zlist) = plotlist

        # Plot individual vertices:
        # if vertexfill:
        #     for vertex in face.vertices():
        #         plot_vertex(axes, vertex)

        # Plot edges that connect vertices:
        for i in range(-1, len(xlist) - 1):
            axes.plot3D([xlist[i], xlist[i + 1]], [ylist[i], ylist[i + 1]],
                        [zlist[i], zlist[i + 1]],
                        linecolour,
                        alpha=linealpha,
                        lw=linewidth)

        # Plot the face surface:
        if facefill:
            plotlist_xyz = plotlist2plotlist_xyz(plotlist)
            fs = mp3d.art3d.Poly3DCollection([plotlist_xyz], linewidth=0)
            if not illumination:
                (nR, nG, nB) = hex2nRGB(facecolour)
                fs.set_facecolor((nR, nG, nB, facealpha))
                axes.add_collection3d(fs)
            else:
                value = round(0.1 + 0.9 / 1.6 * ill_value, 2)
                fs.set_facecolor((value, value, value, facealpha))
                axes.add_collection3d(fs)