16 #include "Base/Util/Assert.h"
17 #include "Sample/Aggregate/Interference2DParaCrystal.h"
21 void ResizeLatticePositions(std::vector<std::vector<double>>& lattice_positions,
double l1,
22 double l2,
double layer_size)
27 n1 = l1 == 0.0 ? 2 :
static_cast<int>(layer_size * 2 / l1);
28 n2 = l2 == 0.0 ? 2 :
static_cast<int>(layer_size * 2 / l2);
30 n1 = std::max(n1, n2);
32 lattice_positions.resize((2 * n1 + 1) * (2 * n1 + 1));
33 for (
auto& it : lattice_positions)
36 lattice_positions[0][0] = 0.0;
37 lattice_positions[0][1] = 0.0;
40 void FindLatticePositionsIndex(
size_t& index,
size_t& index_prev,
int i,
int j,
int size,
43 int newindex = i * (2 * size + 1) + j;
47 if (std::sin(l_alpha) == 0) {
50 index_prev =
static_cast<size_t>(i * (2 * size + 1));
52 index_prev = index - 2;
55 index_prev =
static_cast<size_t>(j);
57 index_prev = index -
static_cast<size_t>(2 * (2 * size + 1));
61 std::pair<double, double> ComputePositionAlongPositiveLatticeVector(
62 const size_t index_prev, std::vector<std::vector<double>>& lattice_positions,
63 const IProfile2D* pdf,
double l,
double l_xi,
double l_alpha)
65 double gamma_pdf = pdf->gamma();
66 std::pair<double, double> sampleXYpdf = pdf->createSampler()->randomSample();
68 double offset_x_pdf = sampleXYpdf.first;
69 double offset_y_pdf = sampleXYpdf.second;
71 double x = lattice_positions[index_prev][0] + l * std::cos(l_xi + l_alpha)
72 + offset_x_pdf * std::cos(gamma_pdf + l_xi)
73 + offset_y_pdf * std::cos(M_PI_2 + gamma_pdf + l_xi);
74 double y = lattice_positions[index_prev][1] + l * std::sin(l_xi + l_alpha)
75 + offset_x_pdf * std::sin(gamma_pdf + l_xi)
76 + offset_y_pdf * std::sin(M_PI_2 + gamma_pdf + l_xi);
78 return std::make_pair(x, y);
81 std::pair<double, double> ComputePositionAlongNegativeLatticeVector(
82 const size_t index_prev, std::vector<std::vector<double>>& lattice_positions,
83 const IProfile2D* pdf,
double l,
double l_xi,
double l_alpha)
85 double gamma_pdf = pdf->gamma();
86 std::pair<double, double> sampleXYpdf = pdf->createSampler()->randomSample();
88 double offset_x_pdf = sampleXYpdf.first;
89 double offset_y_pdf = sampleXYpdf.second;
91 double x = lattice_positions[index_prev][0] - l * std::cos(l_xi + l_alpha)
92 + offset_x_pdf * std::cos(gamma_pdf + l_xi)
93 + offset_y_pdf * std::cos(M_PI_2 + gamma_pdf + l_xi);
94 double y = lattice_positions[index_prev][1] - l * std::sin(l_xi + l_alpha)
95 + offset_x_pdf * std::sin(gamma_pdf + l_xi)
96 + offset_y_pdf * std::sin(M_PI_2 + gamma_pdf + l_xi);
98 return std::make_pair(x, y);
101 std::pair<double, double>
102 ComputeLatticePosition(
const size_t index_prev,
int i,
int j,
103 std::vector<std::vector<double>>& lattice_positions,
const IProfile2D* pdf,
104 double l,
double l_xi,
double l_alpha)
106 if (std::sin(l_alpha) == 0) {
108 return ComputePositionAlongPositiveLatticeVector(index_prev, lattice_positions, pdf, l,
111 return ComputePositionAlongNegativeLatticeVector(index_prev, lattice_positions, pdf, l,
115 return ComputePositionAlongPositiveLatticeVector(index_prev, lattice_positions, pdf, l,
118 return ComputePositionAlongNegativeLatticeVector(index_prev, lattice_positions, pdf, l, l_xi,
122 void ComputePositionsAlongLatticeVectorAxes(std::vector<std::vector<double>>& lattice_positions,
123 const IProfile2D* pdf,
double l,
double l_xi,
126 int n =
static_cast<int>((std::sqrt(lattice_positions.size()) - 1) / 2);
129 size_t index_prev = 0;
131 std::pair<double, double> xy;
133 for (
int iter = 1; iter <= 2 * n; ++iter) {
136 if (std::sin(l_alpha) == 0) {
150 FindLatticePositionsIndex(index, index_prev, iterl2, iterl1, n, l_alpha);
151 xy = ComputeLatticePosition(index_prev, iterl2, iterl1, lattice_positions, pdf, l, l_xi,
154 lattice_positions[index][0] = xy.first;
155 lattice_positions[index][1] = xy.second;
159 void ComputePositionsInsideLatticeQuadrants(std::vector<std::vector<double>>& lattice_positions,
160 const IProfile2D* pdf1,
const IProfile2D* pdf2,
161 double l1,
double l2,
double l_xi,
double l_alpha)
163 int n =
static_cast<int>((std::sqrt(lattice_positions.size()) - 1) / 2);
166 size_t index_prev = 0;
168 std::pair<double, double> xy_l1, xy_l2;
170 for (
int i = 1; i <= 2 * n; ++i) {
171 for (
int j = 1; j <= 2 * n; ++j) {
172 FindLatticePositionsIndex(index, index_prev, i, j, n, 0);
173 xy_l1 = ComputeLatticePosition(index_prev, i, j, lattice_positions, pdf1, l1, l_xi, 0);
175 FindLatticePositionsIndex(index, index_prev, i, j, n, l_alpha);
176 xy_l2 = ComputeLatticePosition(index_prev, i, j, lattice_positions, pdf2, l2, l_xi,
179 lattice_positions[index][0] = (xy_l1.first + xy_l2.first) / 2;
180 lattice_positions[index][1] = (xy_l1.second + xy_l2.second) / 2;
192 std::vector<std::vector<double>>
196 const auto& lattice = p_iff->lattice();
197 double l1 = lattice.length1();
198 double l2 = lattice.length2();
199 double alpha = lattice.latticeAngle();
200 double xi = lattice.rotationAngle();
202 std::vector<std::vector<double>> lattice_positions;
203 ResizeLatticePositions(lattice_positions, l1, l2, layer_size);
205 ComputePositionsAlongLatticeVectorAxes(lattice_positions, p_iff->pdf1(), l1, xi, 0);
207 ComputePositionsAlongLatticeVectorAxes(lattice_positions, p_iff->pdf2(), l2, xi, alpha);
209 ComputePositionsInsideLatticeQuadrants(lattice_positions, p_iff->pdf1(), p_iff->pdf2(), l1, l2,
212 return lattice_positions;
Defines namespace GUI::RealSpace::Paracrystal2D.
std::vector< std::vector< double > > latticePositions(const Interference2DParaCrystal *, double layer_size)