3D сюжет КОНУСА с использованием matplotlib

Закрытия просты:

Следующий простой пример охватывает все основные моменты закрытия JavaScript. * & nbsp;

Вот фабрика, которая производит калькуляторы, которые могут добавлять и умножать:

function make_calculator() {
  var n = 0; // this calculator stores a single number n
  return {
    add: function(a) {
      n += a;
      return n;
    },
    multiply: function(a) {
      n *= a;
      return n;
    }
  };
}

first_calculator = make_calculator();
second_calculator = make_calculator();

first_calculator.add(3); // returns 3
second_calculator.add(400); // returns 400

first_calculator.multiply(11); // returns 33
second_calculator.multiply(10); // returns 4000

Ключевой момент: каждый вызов make_calculator создает новую локальную переменную n, которая по-прежнему может использоваться функциями add и multiply этого калькулятора после make_calculator возвращается.

Если вы знакомы с кадрами стека, эти калькуляторы кажутся странными: как они могут продолжать доступ к n после возвращения make_calculator? Ответ заключается в том, чтобы предположить, что JavaScript не использует «фреймы стека», но вместо этого использует «кучевые кадры», которые могут сохраняться после вызова функции, которая заставила их вернуться.

Внутренние функции, такие как add и multiply, которые передают переменные, объявленные во внешней функции **, называются замыканиями .

Это почти все, что есть для закрытия.


* Например, он охватывает все точки в статье «Закрытия для чайников», приведенные в , другой ответ , за исключением примера 6, который просто показывает что переменные могут использоваться до того, как они будут объявлены, хороший факт, чтобы знать, но полностью не связан с закрытием. Он также охватывает все точки из принятого ответа , за исключением точек (1), которые копируют свои аргументы в локальные переменные (именованные аргументы функции) и (2) что копирование чисел создает новый номер, но копирование ссылки на объект дает вам другую ссылку на тот же объект. Они также хорошо знают, но снова полностью не связаны с закрытием. Он также очень похож на пример в этого ответа , но немного короче и менее абстрактен. Он не охватывает точку этого ответа или этого комментария , который заключается в том, что JavaScript затрудняет подключение значения current для переменной цикла в вашу внутреннюю функцию: шаг «запирания» может выполняться только с помощью вспомогательной функции, которая включает вашу внутреннюю функцию и вызывается на каждой итерации цикла. (Строго говоря, внутренняя функция обращается к копии переменной вспомогательной функции, а не к чему-либо подключенному.) Опять же, очень полезно при создании закрытий, но не в части того, что такое закрытие или как оно работает. Существует дополнительная путаница из-за того, что замыкания работают по-разному в функциональных языках, таких как ML, где переменные привязаны к значениям, а не к пространству хранения, обеспечивая постоянный поток людей, которые понимают закрытие способом (а именно «подключаемым» способом), который просто неверный для JavaScript, где переменные всегда привязаны к пространству хранения и никогда не относятся к значениям.

** Любая внешняя функция, если несколько вложенных или даже в глобальном контексте, как , этот ответ четко указывает.

0
задан kking 22 March 2019 в 12:05
поделиться

1 ответ

Я нашел решение, может быть, оно будет полезно для других.

from mpl_toolkits.mplot3d import Axes3D

from matplotlib import cm

import matplotlib.pyplot as plt

import numpy as np
import colorsys


from matplotlib.tri import Triangulation

from mpl_toolkits.mplot3d.art3d import Poly3DCollection


n_angles = 80

n_radii = 20


# An array of radii

# Does not include radius r=0, this is to eliminate duplicate points

radii = np.linspace(0.0, 0.5, n_radii)


# An array of angles

angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)


# Repeat all angles for each radius

angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)


# Convert polar (radii, angles) coords to cartesian (x, y) coords

# (0, 0) is added here. There are no duplicate points in the (x, y) plane


x = np.append(0, (radii*np.cos(angles)).flatten())

y = np.append(0, (radii*np.sin(angles)).flatten())


# Pringle surface

z = 1+-np.sqrt(x**2+y**2)*2


print(x.shape, y.shape, angles.shape, radii.shape, z.shape)

# NOTE: This assumes that there is a nice projection of the surface into the x/y-plane!
tri = Triangulation(x, y)

triangle_vertices = np.array([np.array([[x[T[0]], y[T[0]], z[T[0]]],

                                        [x[T[1]], y[T[1]], z[T[1]]],

                                        [x[T[2]], y[T[2]], z[T[2]]]]) for T in tri.triangles])


x2 = np.append(0, (radii*np.cos(angles)).flatten())

y2 = np.append(0, (radii*np.sin(angles)).flatten())


# Pringle surface
z2 = -1+np.sqrt(x**2+y**2)*2


# NOTE: This assumes that there is a nice projection of the surface into the x/y-plane!
tri2 = Triangulation(x2, y2)

triangle_vertices2 = np.array([np.array([[x2[T[0]], y2[T[0]], z2[T[0]]],

                                        [x2[T[1]], y2[T[1]], z2[T[1]]],

                                        [x2[T[2]], y2[T[2]], z2[T[2]]]]) for T in tri2.triangles])

triangle_vertices = np.concatenate([triangle_vertices, triangle_vertices2])

midpoints = np.average(triangle_vertices, axis=1)


def find_color_for_point(pt):

    c_x, c_y, c_z = pt

    angle = np.arctan2(c_x, c_y)*180/np.pi

    if (angle < 0):
        angle = angle + 360

    if c_z < 0:

        l = 0.5 - abs(c_z)/2
        #l=0
    if c_z == 0:
        l = 0.5
    if c_z > 0:
        l = (1 - (1-c_z)/2)

    if c_z > 0.97:

        l = (1 - (1-c_z)/2)

    col = colorsys.hls_to_rgb(angle/360, l, 1)

    return col


facecolors = [find_color_for_point(pt) for pt in midpoints]  # smooth gradient
# facecolors = [np.random.random(3) for pt in midpoints]  # random colors


coll = Poly3DCollection(
    triangle_vertices, facecolors=facecolors, edgecolors=None)


fig = plt.figure()

ax = fig.gca(projection='3d')

ax.add_collection(coll)

ax.set_xlim(-1, 1)

ax.set_ylim(-1, 1)

ax.set_zlim(-1, 1)

ax.elev = 50


plt.show()
0
ответ дан kking 22 March 2019 в 12:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: