public void DrawConfiguration(SystemConfig self) { m_Canvas.Series.Clear(); DrawCircle circle = (alpha, R) => { return(new double[] { R *Math.Cos(alpha), R *Math.Sin(alpha) }); }; // plot crystall; var phi_max = Math.Asin(0.5 * self.crystalW / self.crystalR); int N = (int)(2.0 * phi_max / 0.001); var phis = Vector <double> .Build.Dense(N, i => - phi_max + i * 0.001); phis = phis + Math.PI / 2.0; PlotCircle(circle, phis, self.crystalR, "#FF0000", 5); // plot source; /* elipse = lambda alpha, size, shift: [size[0] * np.cos(alpha) + shift[0], size[1] * np.sin(alpha) + shift[1]]; * b_phi = self.BraggA * np.pi / 180.0; * source_pos = [-self.SrcDist * np.cos(b_phi), -self.SrcDist * np.sin(b_phi) - self.crystalR]; * figure_ax.plot(*elipse(np.arange(-np.pi, np.pi, 0.001), [self.SrcSizeW, self.SrcSizeH], source_pos),; * color = "blue");*/ // plot detector; var b_phi = self.BraggA * Math.PI / 180.0; double[] source_pos = { -self.SrcDist * Math.Cos(b_phi), -self.SrcDist * Math.Sin(b_phi) + self.crystalR }; var detector_center = new double[] { self.DstDist *Math.Cos(b_phi), -self.DstDist * Math.Sin(b_phi) + self.crystalR }; double[] R_position = { 0, 0, 0 }; var detector_norm_line = Extension.Sub(detector_center, R_position); var norm = Extension.vectorLenght(detector_norm_line); detector_norm_line = detector_norm_line.Select(x => x / norm).ToArray(); var detector_half_size = 20.0; if (self.waveLimits != null) { detector_half_size = (Math.Abs(self.waveLimits.max.position) + Math.Abs(self.waveLimits.min.position)) * 1.25; } N = (int)(2.0 * detector_half_size / 0.1); var step = Vector <double> .Build.Dense(N, i => - detector_half_size + i * 0.1); var r0 = detector_center; var direction = detector_norm_line; Func <double, double[]> line = (steps) => { return(new double[] { steps *direction[0] + r0[0], steps *direction[1] + r0[1] }); }; PlotFunc(line, step, "#00FF00", 5); // plot object; if (self.ObjectExist) { var object_distance = self.Object.GridPosition; double[] object_coord = { ((self.Object.GridLocation == 0) ? -1 : 1) * object_distance * Math.Cos(b_phi), -object_distance * Math.Sin(b_phi) + self.crystalR }; double[] object_vector = { -object_coord[0], self.crystalR - object_coord[1] }; double tmp = object_vector[0]; double object_vector_norm = Extension.vectorLenght(object_vector); object_vector[0] = -object_vector[1] / object_vector_norm; object_vector[1] = tmp / object_vector_norm; var ObjectN = (int)(self.Object.GridWidth / 0.1); var object_t_step = Vector <double> .Build.Dense(ObjectN, i => - self.Object.GridWidth / 2.0 + i *0.1); Func <double, double[]> object_line = (steps) => { return(new double[] { steps *object_vector[0] + object_coord[0], steps *object_vector[1] + object_coord[1] }); }; PlotFunc(object_line, object_t_step, "#00FFFF", 3); } // plot lines; var dh = Math.Sqrt(self.crystalR * self.crystalR - self.crystalW * self.crystalW / 4.0); double[] cross_point_1 = { -self.crystalW / 2.0, dh }; double[] cross_point_2 = { self.crystalW / 2.0, dh }; Func <double, double[], double[], double[]> lpoint = (steps, r0p, directionP) => { return(new double[] { steps *directionP[0] + r0p[0], steps *directionP[1] + r0p[1] }); }; var detector_cross_1 = lpoint((self.waveLimits != null) ? self.waveLimits.max.position : 10, detector_center, detector_norm_line); var detector_cross_2 = lpoint((self.waveLimits != null) ? self.waveLimits.min.position : -10, detector_center, detector_norm_line); PlotPoints(new double[] { source_pos[0], cross_point_1[0], detector_cross_1[0] }, new double[] { source_pos[1], cross_point_1[1], detector_cross_1[1] }, "#0000FF", 1); PlotPoints(new double[] { source_pos[0], cross_point_2[0], detector_cross_2[0] }, new double[] { source_pos[1], cross_point_2[1], detector_cross_2[1] }, "#FF0000", 1); // plot Roland circle; double[] RowlandCenter = { 0.0, -self.crystalR / 2.0 }; N = (int)(Math.PI * 2 / 0.001); phis = Vector <double> .Build.Dense(N, i => - Math.PI + i * 0.001); Func <double, double[]> sh_circle = (alpha) => { return(new double[] { self.crystalR / 2.0 * Math.Cos(alpha) - RowlandCenter[0], self.crystalR / 2.0 * Math.Sin(alpha) - RowlandCenter[1] }); }; PlotFunc(sh_circle, phis, "#000000", 2, LineStyle.Dash); // plot normal to crystal and start of the system; PlotPoints(new double[] { 0.0, 0.0 }, new double[] { self.crystalR, -self.crystalR }, "#000000", 2, LineStyle.Dash); m_Canvas.ResetAllAxes(); }
private void GetLimitWaves() { var phi = BraggA * Math.PI / 180.0; var L = SrcDist; var R = crystalR; var H = crystalW / 2.0; var D = DstDist; double[] CR = { 0.0, L *Math.Sin(phi) - R }; double[] SR = { -L * Math.Cos(phi), 0 }; var S = CR[1] + Math.Sqrt(R * R - H * H); double[] detector_center = { D *Math.Cos(phi), CR[1] + R - D * Math.Sin(phi) }; var detector_norm_line = Extension.Sub(detector_center, SR); detector_norm_line = detector_norm_line.Select(d => d / Extension.vectorLenght(detector_norm_line)).ToArray(); double[] detector_cross_line = { detector_norm_line[0], detector_norm_line[1] }; List <double> waves = new List <double>(); List <double> position = new List <double>(); List <double[]> limit_line_cross_point = new List <double[]>(); List <double> limit_line_position = new List <double>(); foreach (var mult in new double[] { -1.0, 1.0 }) { double[] CrossR = { mult *H, S }; var r1 = Extension.Sub(SR, CrossR); var r2 = Extension.Sub(CR, CrossR); var cosT = Extension.dot(r1, r2) / (Math.Sqrt(Extension.dot(r1, r1)) * Math.Sqrt(Extension.dot(r2, r2))); var Theta = Math.PI / 2.0 - Math.Acos(cosT); var P = (CrystalProps.crystal2d[mainOrder - 1] / mainOrder) * Math.Sin(Theta); waves.Add(P); Theta = Math.PI / 2 - Theta; var cos2T = Math.Cos(-Theta); var sin2T = Math.Sin(-Theta); double[,] rotation_matrix_vec = { { cos2T, -sin2T }, { sin2T, cos2T } }; var rotation_matrix = Matrix <double> .Build.DenseOfArray(rotation_matrix_vec); r2 = r2.Select(x => x / Extension.vectorLenght(r2)).ToArray(); var mirror_to_detector = Vector <double> .Build.DenseOfArray(r2) * rotation_matrix; mirror_to_detector.Divide(Extension.vectorLenght(mirror_to_detector.ToArray())); var A_array = new double[, ] { { mirror_to_detector[0], mirror_to_detector[1] }, { detector_cross_line[0], detector_cross_line[1] } }; var A = Matrix <double> .Build.DenseOfArray(A_array).Transpose(); var B_array = Extension.Sub(detector_center, CrossR); var B = Vector <double> .Build.DenseOfArray(B_array).ToColumnMatrix(); A = A.Inverse(); var cross_t = A.Multiply(B).ToRowMajorArray(); var cross_point = detector_cross_line.Select(x => x * cross_t[1]).ToArray(); limit_line_cross_point.Add(cross_point); var cross_position = Extension.vectorLenght(cross_point); position.Add(mult * cross_position); limit_line_position.Add(mult * cross_position); } var limit_wave_length = new double[] { waves.Max(), waves.Min() }; waveLimits = new WaveLimits(); waveLimits.max = new WaveLimit() { lambda = Math.Round(waves.Max(), 5), position = Math.Round(position[1], 5), }; waveLimits.min = new WaveLimit() { lambda = Math.Round(waves.Min(), 5), position = Math.Round(position[0], 5) }; onWaveLimitChange?.Invoke(this, waveLimits); }