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()); } } }
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); }