Example #1
0
 private void setVector()
 {
     if (formMain.Crystal.A * formMain.Crystal.B * formMain.Crystal.C != 0)
     {
         if (radioButtonRange.Checked)
         {
             formMain.Crystal.SetVectorOfAxis((int)numericBox1.Value, (int)numericBox2.Value, (int)numericBox3.Value);
             formMain.Crystal.SetVectorOfPlane((int)numericBox1.Value, (int)numericBox2.Value, (int)numericBox3.Value);
         }
         else if (radioButtonSpecifiedIndices.Checked)
         {
             var planeIndices = new List <(int H, int K, int L)>();
             var axisIndices  = new List <(int U, int V, int W)>();
             foreach (object o in listBoxSpecifiedIndices.Items)
             {
                 string[] str = ((string)o).Split(new char[] { ' ' });
                 int      x = Convert.ToInt32(str[0]), y = Convert.ToInt32(str[1]), z = Convert.ToInt32(str[2]);
                 if (!checkBoxIncludingEquivalentPlanes.Checked)
                 {
                     planeIndices.Add((x, y, z));
                     axisIndices.Add((x, y, z));
                 }
                 else
                 {
                     axisIndices.AddRange(SymmetryStatic.GenerateEquivalentAxes(x, y, z, formMain.Crystal.Symmetry));
                     planeIndices.AddRange(SymmetryStatic.GenerateEquivalentPlanes(x, y, z, formMain.Crystal.Symmetry));
                 }
             }
             formMain.Crystal.SetVectorOfAxis(axisIndices.ToArray());
             formMain.Crystal.SetVectorOfPlane(planeIndices.ToArray());
         }
     }
 }
Example #2
0
        public double[][] generateDensityArrayNormal(double angleResolution)
        {
            if (crystal == null || crystal.Crystallites == null)
            {
                return(null);
            }

            int x = (int)numericUpDown1.Value, y = (int)numericUpDown2.Value, z = (int)numericUpDown3.Value;

            //double[][] pixelsを初期化
            int radialDivision = (int)(Math.PI / angleResolution / 2);

            double[][] pixels  = new double[radialDivision][];
            for (int i = 0; i < radialDivision; i++)
            {
                double circumference  = (i + 0.5) / radialDivision * Math.PI * 2;
                int    sectorDivision = (int)Math.Round(circumference * radialDivision, MidpointRounding.ToEven);
                pixels[i] = new double[sectorDivision];
                for (int j = 0; j < pixels[i].Length; j++)
                {
                    pixels[i][j] = 0;
                }
            }

            //前回の条件と同じとき
            if (index != null && index.Length == Crystal.Crystallites.Rotations.Length)
            {
                if (x == justBeforeX && y == justBeforeY && z == justBeforeZ && angleResolution == justBeforeResolution && crystal.Crystallites.Rotations.Length == justBeforeCrystallineNumber &&
                    justBeforePoleFigureMode == radioButtonPoleFigure.Checked && justBeforePlanesMode == radioButtonPlanes.Checked)
                {
                    for (int i = 0; i < crystal.Crystallites.Rotations.Length; i++)
                    {
                        foreach (int p in index[i])
                        {
                            pixels[p / ushort.MaxValue][p % ushort.MaxValue] += crystal.Crystallites.Density[i] * crystal.Crystallites.SolidAngle[i];
                        }
                    }
                    for (int radial = 0; radial < pixels.Length; radial++)
                    {
                        double area = (1.0 + 2 * radial) / pixels[radial].Length;
                        for (int sector = 0; sector < pixels[radial].Length; sector++)
                        {
                            pixels[radial][sector] /= 10000 * area;
                        }
                    }
                    return(pixels);
                }
            }
            else
            {
                index = new uint[Crystal.Crystallites.Rotations.Length][];
            }
            justBeforeX          = x; justBeforeY = y; justBeforeZ = z; justBeforeCrystallineNumber = crystal.Crystallites.Rotations.Length;
            justBeforeResolution = angleResolution; justBeforePoleFigureMode = radioButtonPoleFigure.Checked; justBeforePlanesMode = radioButtonPlanes.Checked;

            Symmetry sym = crystal.Symmetry;

            Vector3DBase[] srcVector;

            //Normal
            if (radioButtonPoleFigure.Checked)
            {
                if (radioButtonPlanes.Checked)
                {//計算する面指数と等価な指数を算出
                    var indices = SymmetryStatic.GenerateEquivalentPlanes(x, y, z, sym);
                    srcVector = new Vector3DBase[indices.Length];
                    for (int k = 0; k < indices.Length; k++)
                    {
                        srcVector[k] = crystal.A_Star * indices[k].H + crystal.B_Star * indices[k].K + crystal.C_Star * indices[k].L;
                        if (srcVector[k].Length2 > 0)
                        {
                            srcVector[k] /= srcVector[k].Length;
                        }
                    }
                }
                else
                {//計算する軸指数と等価な指数を算出
                    var indices = SymmetryStatic.GenerateEquivalentAxes(x, y, z, sym);
                    //indices = new AxisIndex[] { new AxisIndex(0, 0, 1) };
                    srcVector = new Vector3DBase[indices.Length];
                    for (int k = 0; k < indices.Length; k++)
                    {
                        srcVector[k] = crystal.A_Axis * indices[k].U + crystal.B_Axis * indices[k].V + crystal.C_Axis * indices[k].W;
                        if (srcVector[k].Length2 > 0)
                        {
                            srcVector[k] /= srcVector[k].Length;
                        }
                    }
                }
            }
            //Inverse
            else
            {
                srcVector = new Vector3DBase[] { new Vector3DBase(x, y, z) };
                if (srcVector[0].Length2 > 0)
                {
                    srcVector[0] /= srcVector[0].Length;
                }
            }

            List <uint> tempIndex = new List <uint>();

            for (int i = 0; i < crystal.Crystallites.Rotations.Length; i++)
            {
                tempIndex.Clear();
                Matrix3D rot = crystal.Crystallites.Rotations[i] * Crystallite.TiltMatrix;

                Vector3DBase[] vectors = new Vector3DBase[srcVector.Length];
                if (radioButtonPoleFigure.Checked)//PoleFigureのとき
                {
                    for (int j = 0; j < vectors.Length; j++)
                    {
                        vectors[j] = rot * srcVector[j];
                    }
                }
                else//InversePoleFigureのとき
                {
                    vectors = divideVector(rot.Transpose() * srcVector[0], sym);
                }

                foreach (Vector3DBase v in vectors)
                {
                    if (v.Z > 0)
                    {
                        PointD pt     = new PointD(v.X / Math.Sqrt(1 + v.Z), v.Y / Math.Sqrt(1 + v.Z));
                        int    radial = (int)Math.Round(pt.Length * radialDivision - 0.5, MidpointRounding.ToEven);
                        if (radial < pixels.Length)
                        {
                            int sector = (int)Math.Round(Math.Atan2(pt.Y, pt.X) / 2 / Math.PI * pixels[radial].Length, MidpointRounding.ToEven);
                            if (sector < 0)
                            {
                                sector += pixels[radial].Length;
                            }
                            //lock (lockObject)
                            pixels[radial][sector] += crystal.Crystallites.Density[i] * crystal.Crystallites.SolidAngle[i];
                            tempIndex.Add((uint)(radial * ushort.MaxValue + sector));
                        }
                    }
                }
                index[i] = tempIndex.ToArray();
            }

            //最後に面積を計算して規格化
            for (int radial = 0; radial < pixels.Length; radial++)
            {
                double area = (1.0 + 2 * radial) / pixels[radial].Length;
                for (int sector = 0; sector < pixels[radial].Length; sector++)
                {
                    pixels[radial][sector] /= 10000 * area;
                }
            }
            return(pixels);
        }