Exemplo n.º 1
0
    def setSurface(self):
        # Crea i valori immagine per la superficie, calcolando su ogni punto della plotTriangulation il valore della superficie di Bezier triangolare sul triangolo PS al quale il punto appartiene.

        # Raffinamento uniforme della triangolazione Powell_Sabin ai fini del plottaggio.
        refiner = UniformTriRefiner(self.domain.PowellSabinTr)
        self.plotTriangulation, self.TrIndex = refiner.refine_triangulation(
            return_tri_index=True, subdiv=4)

        # Salvo i punti della triangolazione iniziale in un solo array.
        self.plotPoints = np.array(
            list(zip(self.plotTriangulation.x, self.plotTriangulation.y)))

        # Inizializzo l'array delle ordinate.
        plotHeights = []

        for point_index in range(len(self.plotPoints)):
            point = self.plotPoints[point_index]

            # Ricerco il triangolo PS al quale appartiene il punto.
            m = self.TrIndex[point_index]
            triangle = self.domain.PS_triangles[m]
            tr_vertexes = np.array(
                [self.domain.PS_points[i] for i in triangle])

            # Ricavo le coordinate baricentriche bc del punto rispetto al triangolo PS.
            bc = self.getBarycentricCoords(tr_vertexes, point)

            # Calcolo l'ordinata associata al punto.
            plotHeights.append(self.triDeCasteljau(m, (0, 0, 0), bc, 3))

            # Salvo array delle ordinate.
            self.plotHeights = np.array(plotHeights)
Exemplo n.º 2
0
    def plot_simplex(self, num_contours: int = 100, num_sub_div: int = 8,
                     color_map: str = 'viridis', border: bool = True,
                     ax: Optional[Axes] = None,
                     **kwargs) -> Axes:
        """
        Plot a 3-dimensional functions as a simplex heat-map.

        :param num_contours: The number of levels of contours to plot.
        :param num_sub_div: Number of recursive subdivisions to create.
        :param color_map: Optional colormap for the plot.
        :param border: Whether to plot a border around the simplex heat-map.
        :param ax: Optional matplotlib axes to plot on.
        :param kwargs: Additional arguments for tricontourf method.
        """
        corners = array([[0, 0], [1, 0], [0.5, 0.75 ** 0.5]])
        triangle = Triangulation(corners[:, 0], corners[:, 1])
        mid_points = [
            (corners[(i + 1) % 3] + corners[(i + 2) % 3]) / 2
            for i in range(3)
        ]

        def to_barycentric(cartesian):
            """
            Converts 2D Cartesian to barycentric coordinates.

            :param cartesian: A length-2 sequence containing the x and y value.
            """
            s = [(corners[i] - mid_points[i]).dot(
                     cartesian - mid_points[i]
                 ) / 0.75
                 for i in range(3)]
            s_clipped = clip(a=s, a_min=0, a_max=1)
            return s_clipped / norm(s_clipped, ord=1)

        refiner = UniformTriRefiner(triangle)
        tri_mesh = refiner.refine_triangulation(subdiv=num_sub_div)
        f = [self._method(to_barycentric(xy))
             for xy in zip(tri_mesh.x, tri_mesh.y)]
        ax = ax or new_axes()
        ax.tricontourf(tri_mesh, f, num_contours, cmap=color_map, **kwargs)
        ax.set_aspect('equal')
        ax.set_xlim(0, 1)
        ax.set_ylim(0, 0.75 ** 0.5)
        ax.set_axis_off()
        if border:
            ax.triplot(triangle, linewidth=1)

        return ax
Exemplo n.º 3
0
def _two_dimension_triangle_func_val(function, num_sample_points):
    """Calculate the triangulation and function values for a given 2D function

    :arg function: 2D function
    :arg num_sample_points: Number of sampling points.  This is not
       obeyed exactly, but a linear triangulation is created which
       matches it reasonably well.
    """
    from math import log
    try:
        from matplotlib.tri import Triangulation, UniformTriRefiner
    except ImportError:
        raise RuntimeError("Matplotlib not importable, is it installed?")
    if function.function_space().mesh().ufl_cell() == Cell('triangle'):
        x = np.array([0, 0, 1])
        y = np.array([0, 1, 0])
    elif function.function_space().mesh().ufl_cell() == Cell('quadrilateral'):
        x = np.array([0, 0, 1, 1])
        y = np.array([0, 1, 0, 1])
    else:
        raise RuntimeError("Unsupported Functionality")
    base_tri = Triangulation(x, y)
    refiner = UniformTriRefiner(base_tri)
    sub_triangles = int(log(num_sample_points, 4))
    tri = refiner.refine_triangulation(False, sub_triangles)
    triangles = tri.get_masked_triangles()
    x_ref = tri.x
    y_ref = tri.y
    num_verts = triangles.max() + 1
    num_cells = function.function_space().cell_node_list.shape[0]
    ref_points = np.dstack([x_ref, y_ref]).reshape(-1, 2)
    z_vals = _calculate_values(function, ref_points, 2)
    coords_vals = _calculate_values(function.function_space().
                                    mesh().coordinates,
                                    ref_points, 2)
    Z = z_vals.reshape(-1)
    X = coords_vals.reshape(-1, 2).T[0]
    Y = coords_vals.reshape(-1, 2).T[1]
    add_idx = np.arange(num_cells).reshape(-1, 1, 1) * num_verts
    all_triangles = (triangles + add_idx).reshape(-1, 3)
    triangulation = Triangulation(X, Y, triangles=all_triangles)
    return triangulation, Z
Exemplo n.º 4
0
def _two_dimension_triangle_func_val(function, num_sample_points):
    """Calculate the triangulation and function values for a given 2D function

    :arg function: 2D function
    :arg num_sample_points: Number of sampling points.  This is not
       obeyed exactly, but a linear triangulation is created which
       matches it reasonably well.
    """
    from math import log
    try:
        from matplotlib.tri import Triangulation, UniformTriRefiner
    except ImportError:
        raise RuntimeError("Matplotlib not importable, is it installed?")
    if function.function_space().mesh().ufl_cell() == Cell('triangle'):
        x = np.array([0, 0, 1])
        y = np.array([0, 1, 0])
    elif function.function_space().mesh().ufl_cell() == Cell('quadrilateral'):
        x = np.array([0, 0, 1, 1])
        y = np.array([0, 1, 0, 1])
    else:
        raise RuntimeError("Unsupported Functionality")
    base_tri = Triangulation(x, y)
    refiner = UniformTriRefiner(base_tri)
    sub_triangles = int(log(num_sample_points, 4))
    tri = refiner.refine_triangulation(False, sub_triangles)
    triangles = tri.get_masked_triangles()
    x_ref = tri.x
    y_ref = tri.y
    num_verts = triangles.max() + 1
    num_cells = function.function_space().cell_node_list.shape[0]
    ref_points = np.dstack([x_ref, y_ref]).reshape(-1, 2)
    z_vals = _calculate_values(function, ref_points, 2)
    coords_vals = _calculate_values(function.function_space().
                                    mesh().coordinates,
                                    ref_points, 2)
    Z = z_vals.reshape(-1)
    X = coords_vals.reshape(-1, 2).T[0]
    Y = coords_vals.reshape(-1, 2).T[1]
    add_idx = np.arange(num_cells).reshape(-1, 1, 1) * num_verts
    all_triangles = (triangles + add_idx).reshape(-1, 3)
    triangulation = Triangulation(X, Y, triangles=all_triangles)
    return triangulation, Z