Ejemplo n.º 1
0
        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();
        }
Ejemplo n.º 2
0
        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);
        }