예제 #1
0
def to_surface(mesh):
    """
    Convert Mesh object into pyny.Surface object (used for visualization)
    Inputs:
    mesh (Mesh)

    Return:
    pyny.Surface - converted mesh
    """
    vert = mesh.vertices
    faces = mesh.faces
    surface = []
    for i in range(faces.shape[0]):
        points = vert[faces[i], :]
        surface.append(pyny.Polygon(np.array(points)))
    return pyny.Surface(surface)
예제 #2
0
    def compute_shadows(self):
        """
        Computes the shadoing for the ``pyny.Space`` stored in 
        ``.space`` for the time intervals and Sun positions stored in 
        ``.arg_t`` and ``.sun_pos``, respectively.
        
        The generated information is stored in:
            * **.light_vor** (*ndarray (dtype=bool)*): Array with the 
              points in ``pyny.Space`` as columns and the discretized 
              Sun positions as rows. Indicates whether the points are 
              illuminated in each Sun position.
            * **.light** (*ndarray (dtype=bool)*): The same as 
              ``.light_vor`` but with the time intervals in ``.arg_t``
              as rows instead of the Sun positions.
        
        :returns: None
        """
        from pyny3d.utils import sort_numpy, bool2index, index2bool
        state = pyny.Polygon.verify
        pyny.Polygon.verify = False

        model = self.space
        
        light = []
        for sun in self.vor_centers:
            # Rotation of the whole ``pyny.Space``
            polygons_photo, _, points_to_eval = model.photo(sun, False)
            # Auxiliar pyny.Surface to fast management of pip
            Photo_surface = pyny.Surface(polygons_photo)
            Photo_surface.lock()
           
            # Sort/unsort points
            n_points = points_to_eval.shape[0]
            points_index_0 = np.arange(n_points) # _N indicates the depth level
            points_to_eval, order_back = sort_numpy(points_to_eval, col=0, 
                                                    order_back=True)
            # Loop over the sorted (areas) Polygons
            for i in model.sorted_areas:
                p = points_to_eval[points_index_0][:, :2]
                polygon_photo = Photo_surface[i]
                index_1 = bool2index(polygon_photo.pip(p, sorted_col=0))
                points_1 = points_to_eval[points_index_0[index_1]]
                
                if points_1.shape[0] != 0:
                    # Rotation algebra
                    a, b, c = polygon_photo[:3, :]
                    R = np.array([b-a, c-a, np.cross(b-a,  c-a)]).T
                    R_inv = np.linalg.inv(R)
                    Tr = a # Translation
                    # Reference point (between the Sun and the polygon)
                    reference_point = np.mean((a, b, c), axis=0)
                    reference_point[2] = reference_point[2] - 1
                    points_1 = np.vstack((points_1, reference_point))
                    points_over_polygon = np.dot(R_inv, (points_1-Tr).T).T
                    # Logical stuff
                    shadow_bool_2 = np.sign(points_over_polygon[:-1, 2]) != \
                                    np.sign(points_over_polygon[-1, 2])     
                    shadow_index_2 = bool2index(shadow_bool_2)
                    if shadow_index_2.shape[0] != 0:
                        points_to_remove = index_1[shadow_index_2]
                        points_index_0 = np.delete(points_index_0, 
                                                   points_to_remove)
            
            lighted_bool_0 = index2bool(points_index_0, 
                                        length=points_to_eval.shape[0])
            # Updating the solution
            light.append(lighted_bool_0[order_back])
        # Storing the solution
        self.light_vor = np.vstack(light)
        self.light = self.light_vor[self.t2vor_map]
        pyny.Polygon.verify = state
예제 #3
0
    def Vonoroi_SH(self, mesh_size=0.1):
        """
        Generates a equally spaced mesh on the Solar Horizont (SH).
        
        Computes the Voronoi diagram from a set of points given by pairs
        of (azimuth, zenit) values. This discretization completely
        covers all the Sun positions.
        
        The smaller mesh size, the better resolution obtained. It is 
        important to note that this heavily affects the performance.
        
        The generated information is stored in:
            * **.t2vor_map** (*ndarray*): Mapping between time vector and
              the Voronoi diagram.
            * **.vor_freq** (*ndarray*): Number of times a Sun position
              is inside each polygon in the Voronoi diagram.
            * **.vor_surf** (*``pyny.Surface``*): Voronoi diagram.
            * **.vor_centers** (*ndarray`*): Mass center of the 
              ``pyny.Polygons`` that form the Voronoi diagram.
        
        :param mesh_size: Mesh size for the square discretization of the
            Solar Horizont.
        :type mesh_size: float (in radians)
        :param plot: If True, generates a visualization of the Voronoi
            diagram.
        :type plot: bool
        :returns: None
        
        .. note:: In future versions this discretization will be
            improved substantially. For now, it is quite rigid and only
            admits square discretization.
        """
        from scipy.spatial import Voronoi
        from pyny3d.utils import sort_numpy
        state = pyny.Polygon.verify
        pyny.Polygon.verify = False

        # Sort and remove NaNs
        xy_sorted, order_back = sort_numpy(self.azimuth_zenit, col=1, 
                                           order_back=True)
        
        # New grid
        x1 = np.arange(-np.pi, np.pi, mesh_size)
        y1 = np.arange(-mesh_size*2, np.pi/2+mesh_size*2, mesh_size)
        x1, y1 = np.meshgrid(x1, y1)
        centers = np.array([x1.ravel(), y1.ravel()]).T
        
        # Voronoi
        vor = Voronoi(centers)
        
        # Setting the SH polygons
        pyny_polygons = [pyny.Polygon(vor.vertices[v], False)
                         for v in vor.regions[1:] if len(v) > 3]
        raw_surf = pyny.Surface(pyny_polygons)
                                 
        # Classify data into the polygons discretization
        map_ = raw_surf.classify(xy_sorted, edge=True, col=1, 
                                 already_sorted=True)
        map_ = map_[order_back]
        
        # Selecting polygons with points inside
        vor = []
        count = []
        for i, poly_i in enumerate(np.unique(map_)[1:]):
            vor.append(raw_surf[poly_i])
            bool_0 = map_==poly_i
            count.append(bool_0.sum())
            map_[bool_0] = i
                
        # Storing the information
        self.t2vor_map = map_
        self.vor_freq = np.array(count)
        self.vor_surf = pyny.Surface(vor)
        self.vor_centers = np.array([poly.get_centroid()[:2] 
                                     for poly in self.vor_surf])
        pyny.Polygon.verify = state