public static double GetAngleBetweenHolders(double p1t1, double p1t2, double p2t1, double p2t2) { var v1 = new Vector3D(Math.Sin(p1t1), Math.Cos(p1t1) * Math.Sin(p1t2), Math.Cos(p1t1) * Math.Cos(p1t2)); var v2 = new Vector3D(Math.Sin(p2t1), Math.Cos(p2t1) * Math.Sin(p2t2), Math.Cos(p2t1) * Math.Cos(p2t2)); return(Vector3D.AngleBetVectors(v1, v2)); }
public static ZoneAxes[] ZoneAxisFromTwoZoneAxis(Crystal cry, PhotoInformation photo1, PhotoInformation photo2, bool excludeEquivalence) { //ここからホルダー間の角度上限下限をきめる double angleMax = 0, angleMin = 0; int sign1 = Math.Sign(photo1.Tilt1 - photo2.Tilt1); int sign2 = Math.Sign(photo1.Tilt2 - photo2.Tilt2); if (sign1 == 0) { sign1 = 1; } if (sign2 == 0) { sign2 = 1; } angleMax = GetAngleBetweenHolders( photo1.Tilt1 + sign1 * photo1.Tilt1Err, photo1.Tilt2 + sign2 * photo1.Tilt2Err, photo2.Tilt1 - sign1 * photo2.Tilt1Err, photo2.Tilt2 - sign2 * photo2.Tilt2Err); double p1t1, p1t2, p2t1, p2t2; if (Math.Sign((photo1.Tilt1 - sign1 * photo1.Tilt1Err) - (photo2.Tilt1 + sign1 * photo2.Tilt1Err)) != sign1) { p1t1 = p2t1 = (photo1.Tilt1 + photo2.Tilt1) / 2; } else { p1t1 = photo1.Tilt1 - sign1 * photo1.Tilt1Err; p2t1 = photo2.Tilt1 + sign1 * photo2.Tilt1Err; } if (Math.Sign((photo1.Tilt2 - sign2 * photo1.Tilt2Err) - (photo2.Tilt2 + sign2 * photo2.Tilt2Err)) != sign2) { p1t2 = p2t2 = (photo1.Tilt2 + photo2.Tilt2) / 2; } else { p1t2 = photo1.Tilt2 - sign2 * photo1.Tilt2Err; p2t2 = photo2.Tilt2 + sign2 * photo2.Tilt2Err; } angleMin = GetAngleBetweenHolders(p1t1, p1t2, p2t1, p2t2); //ここから条件にある軸のペアを検索 List <ZoneAxes> zoneAxes = new List <ZoneAxes>(); ZoneAxis[] zoneAxis1 = GetZoneAxis(cry, photo1, excludeEquivalence); ZoneAxis[] zoneAxis2 = GetZoneAxis(cry, photo2, false); for (int n = 0; n < zoneAxis1.Length; n++) { //if (zoneAxis1[n].plane1.IsRootIndex) for (int m = 0; m < zoneAxis2.Length; m++) { Vector3D v1 = zoneAxis1[n].u * cry.A_Axis + zoneAxis1[n].v * cry.B_Axis + zoneAxis1[n].w * cry.C_Axis; Vector3D v2 = zoneAxis2[m].u * cry.A_Axis + zoneAxis2[m].v * cry.B_Axis + zoneAxis2[m].w * cry.C_Axis; double calcAngle = Vector3D.AngleBetVectors(v1, v2); if (angleMax >= calcAngle && angleMin <= calcAngle) { ZoneAxes temp = new ZoneAxes(); temp.Za1 = zoneAxis1[n]; temp.Za2 = zoneAxis2[m]; temp.AngleBet12 = calcAngle; temp.IsTwoPhoho = true; zoneAxes.Add(temp); } } } //excludeEquivalence==true のとき、zoneAxesの中で等価なものを削除する if (excludeEquivalence) { for (int i = 0; i < zoneAxes.Count; i++) { for (int j = i + 1; j < zoneAxes.Count; j++) { if (zoneAxes[i].Za1 == zoneAxes[j].Za1) { var plane1 = zoneAxes[i].Za2.plane1; var plane2 = zoneAxes[i].Za2.plane2; var indices1 = new List <(int H, int K, int L)>(); var indices2 = new List <(int H, int K, int L)>(); SymmetryStatic.IsRootIndex((plane1.h, plane1.k, plane1.l), cry.Symmetry, ref indices1, true); SymmetryStatic.IsRootIndex((plane2.h, plane2.k, plane2.l), cry.Symmetry, ref indices2, true); if (indices1.Contains((zoneAxes[j].Za2.plane1.h, zoneAxes[j].Za2.plane1.k, zoneAxes[j].Za2.plane1.l)) && indices2.Contains((zoneAxes[j].Za2.plane2.h, zoneAxes[j].Za2.plane2.k, zoneAxes[j].Za2.plane2.l))) { zoneAxes.RemoveAt(j); j--; } } } } } return(zoneAxes.ToArray()); }