Генерация распределения интенсивности рассеянного света от точечной частицы с центром на сфере с использованием питона

Я пытаюсь смоделировать частицу в трехмерном пространстве, рассеивая свет с распределением интенсивности, пропорциональным 1+cos(theta)^2, где theta измеряется от плоскости xy. Частица является точечной, и поэтому задача состоит в том, чтобы вычислить массив точек (которые будут преобразованы в векторы положения, действующие как лучи света), которые распределены с плотностью, следующей за распределением 1 + cos (тета) ^ 2.

Моей первой мыслью было использование алгоритма, который равномерно распределяет точки на сфере, а затем настраивает его так, чтобы он соответствовал распределению 1 + cos (theta) ^ 2. Однако наиболее точный из этих методов использует случайные величины для определения точек. Поскольку я хочу иметь возможность включать произвольное количество точек, я бы предпочел, чтобы последний метод не использовал случайную выборку (поскольку небольшая случайная выборка приведет к плохому распределению).

Мне кажется, что это очень стандартная проблема, хотя я не смог найти ничего, что имело бы к ней непосредственное отношение.

Вот код для чего-то, что я собрал вместе (я не опытный кодер, так что извините за плохую форму):

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np


initial_vector = np.array([0,0,-1])

def phi_rotation(phi):
    #  rotation matrix about y axis  anticlockwise with y towards observer  
    return np.array([[np.cos(phi), 0, np.sin(phi)], [0, 1, 0], [-np.sin(phi), 0, np.cos(phi)]])

def theta_rotation(theta):
    #  rotation matrix about x axis clockwise with x pointing towards (not conventional theta from z axis)
    return np.array([[1, 0, 0], [0, np.cos(theta), -np.sin(theta)], [0, np.sin(theta), np.cos(theta)]])


def generate_equi_intensity_ring(theta, param):
    vectors = []
    first_vector = theta_rotation(theta).dot(np.array([0,0,1]))
    dphi = param/(abs(np.cos(theta))*np.sqrt(1+np.cos(theta)**2))

    for phi in np.linspace(0, 2*np.pi-dphi, 2*np.pi/dphi):
        vectors.append(phi_rotation(phi).dot(first_vector))

    return vectors    

def generate_full_array(param):
    theta = -np.pi/2
    thetas = [theta]
    while theta < np.pi/2:
        dtheta = param/np.sqrt(1+np.cos(theta)**2)
        theta += dtheta
        thetas.append(theta)

    equi_intensitiy_arrays = []

    for theta in thetas:
        vectors = generate_equi_intensity_ring(theta, param)  
        if len(vectors) != 0:
            equi_intensitiy_arrays.append(vectors)    

    return np.concatenate(equi_intensitiy_arrays)



vectors = generate_full_array(0.08) 
x, y, z = zip(*vectors)
print(len(x)) # prints number of rays created    

##### PLOTTING COMPARISON OF DENSITY WITH THETA TO 1+COS(THETA)^2 ####
from scipy import stats

xyz = np.vstack([x,y,z])
density = stats.gaussian_kde(xyz)(xyz)     
idx = density.argsort()
x, y ,z = np.array(x), np.array(y) ,np.array(z) 
x, y, z, density = x[idx], y[idx], z[idx], density[idx]

thetas = np.arccos(y)
plt.plot(np.concatenate([thetas, thetas+np.pi]), 2/max(density) * np.concatenate([density for i in range(2)]), ".")
plt.plot(np.arange(0, 2*np.pi, 0.1), [1+np.sin(t)**2 for t in np.arange(0, 2*np.pi, 0.1)], linewidth=2)

Я масштабировал угловое разделение векторов вокруг оси y, чтобы масштабировать как 1/cos(тета), а также 1/(интенсивность) = 1/(1+cos(тета)^2), это сохраняет плотность точек равномерной и останавливает группирование на полюсах. Это также следует из моего определения тета выше и размера телесного угла, созданного dphi и dtheta.

Однако, когда я сравниваю результат с 1 + cos (тета)**2, это не совсем верно: вычисленная плотность точек (синий) и 1 + cos (тета)^2 (зеленый). ось у = плотность, ось х = тета (0,2pi)

(Примечание: я поменял местами мое определение тэты, измеренное от плоскости xy до измерения от оси z (стандарт), для удобства в некоторых местах, так что cos'становятся грехами и т. Д.)

Ясно, что метод не совсем верный, так как вычисленная плотность не разделена (я думаю, что полюса не одинаково сгенерированы относительно друг друга) и неправильно масштабируется.

Любые предложения будут наиболее ценными!

Спасибо

0 ответов

Другие вопросы по тегам