private void CreateTwistMaps() { PermByMatr perm = new PermByMatr(Axes.Length, Faces.Length); foreach (PBaseAxis Ax in BaseAxes) { foreach (PBaseTwist tw in Ax.Twists) { double[,] matr = PGeom.ApplyTwist(tw.Dir, PGeom.MatrixIdentity(Dim)); int[][] R = ConvertStickersFromLayers(Ax, matr, perm); int[][] R1 = new int[Ax.NLayers][]; for (int i = 0; i < Ax.NLayers; i++) { if (R[i] != null) { R1[i] = new int[R[i].Length]; for (int j = 0; j < R[i].Length; j++) { int h = Array.BinarySearch <int>(Ax.Layers[i], R[i][j]); if (h < 0) { throw new Exception("Can't find sticker image in twist"); } R[i][j] = h; R1[i][h] = j; } } } tw.Map = R; tw.InvMap = R1; } } }
private int[][] ConvertStickersFromLayers(PBaseAxis Ax, double[,] matr, PermByMatr P) { for (int i = 0; i < Axes.Length; i++) { P.CvAxes[i] = FindAxis(Axes[i].Dir, matr); } for (int i = 0; i < Faces.Length; i++) { P.CvFaces[i] = FindFace(Faces[i].Pole, matr); } int[][] res = new int[Ax.NLayers][]; for (int i = 0; i < Ax.NLayers; i++) { if (Ax.Layers[i] != null) { int[] rres = (int[])Ax.Layers[i].Clone(); int f0 = -1, f1 = -1; int nca = 0; for (int j = 0; j < rres.Length; j++) { int h = rres[j]; bool cf = false; while (f0 < Faces.Length - 1 && h >= Faces[f0 + 1].FirstSticker) { f0++; cf = true; } if (cf) { f1 = P.CvFaces[f0]; nca = Faces[f0].Base.NCutAxes; P.ReallocPerm(nca); for (int k = 0; k < nca; k++) { int rax = Faces[f0].CutAxes[k]; int pax = Math.Abs(rax) - 1; int s = rax < 0 ? -P.CvAxes[pax] : P.CvAxes[pax]; for (int l = 0; l < nca; l++) { int s1 = Faces[f1].CutAxes[l]; if (s1 == s || s1 == -s) { P.PermAxes[k] = l; P.InvAxes[k] = (s1 != s) ? Axes[pax].Base.NLayers - 1 : 0; s = 0; break; } } if (s != 0) { throw new Exception("Can't find converted cutting axis"); } } } int ns = h - Faces[f0].FirstSticker; for (int k = 0; k < nca; k++) { int m = Faces[f0].Base.StickerMask[ns, k]; if (P.InvAxes[k] != 0) { m = P.InvAxes[k] - m; } P.StkMask[P.PermAxes[k]] = m; } rres[j] = Faces[f1].FirstSticker + Faces[f0].Base.FindByMask(P.StkMask); } res[i] = rres; } } return(res); }
private unsafe void SortStickersForAxes() { int[] S = new int[1000]; foreach (PBaseAxis Ax in BaseAxes) { int nl = Ax.NLayers; int mask = Ax.FixedMask; Ax.Layers = new int[nl][]; for (int i = 0; i < nl; i++) { if (((mask >> i) & 1) == 0) { int ps = 0; foreach (PFace F in Faces) { int ax = FindAxisInv(Ax.Dir, F.Matrix); bool qr = ax < 0; ax = Math.Abs(ax) - 1; PBaseFace BF = F.Base; int i1 = qr ? nl - 1 - i : i; int h = BF.AxisLayers[ax]; int nstk = BF.NStickers; int fstk = F.FirstSticker; if (h >= 0) { if (i1 != h) { continue; } for (int j = 0; j < nstk; j++) { S = SetInt(S, ps++, fstk + j); } } else { int r = Array.IndexOf <int>(BF.CutAxes, ax); if (r < 0) { throw new Exception("Can't find CutAxis"); } byte[,] aa = BF.StickerMask; for (int j = 0; j < nstk; j++) { if (aa[j, r] == i1) { S = SetInt(S, ps++, fstk + j); } } } } int[] ar = new int[ps]; Buffer.BlockCopy(S, 0, ar, 0, sizeof(int) * ps); Ax.Layers[i] = ar; } } } PermByMatr perm = new PermByMatr(Axes.Length, Faces.Length); foreach (PAxis Ax in Axes) { Ax.Layers = ConvertStickersFromLayers(Ax.Base, Ax.Matrix, perm); } }