def project_data(self): ''' Assign the sum of ``.integral``\* to each sensible point in the ``pyny.Space`` for the intervals that the points are visible to the Sun. The generated information is stored in: * **.proj_vor** (*ndarray*): ``.integral`` projected to the Voronoi diagram. * **.proj_points** (*ndarray*): ``.integral`` projected to the sensible points in the ``pyny.Space``. :returns: None .. note:: \* Trapezoidal data (``.arg_data``) integration over time (``.arg_t``). ''' from pyny3d.utils import sort_numpy proj = self.light_vor.astype(float) map_ = np.vstack((self.t2vor_map, self.integral)).T map_sorted = sort_numpy(map_) n_points = map_sorted.shape[0] for i in range(proj.shape[0]): a, b = np.searchsorted(map_sorted[:, 0], (i, i+1)) if b == n_points: b = -1 proj[i, :] *= np.sum(map_sorted[a:b, 1]) self.proj_vor = np.sum(proj, axis=1) self.proj_points = np.sum(proj, axis=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
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