internal double[,] GetBestMatrix(int f0, double[] p0, int f1, double[] p1) { // move from (f0,p0) to (f1,p1); point p is on the cell surface. PFace F0 = Faces[f0], F1 = Faces[f1]; if (F0.Base.Id != F1.Base.Id) { return(null); } double[] q0 = PGeom.ApplyInvMatrix(F0.Matrix, p0); double[] q1 = PGeom.ApplyInvMatrix(F1.Matrix, p1); double dbest = double.MaxValue; double[,] mr = null; foreach (double[,] m in F0.Base.SMatrices) { double[] qq = PGeom.ApplyMatrix(m, q0); double v = PGeom.Dist2(qq, q1); if (v < dbest) { dbest = v; mr = m; } } return(PGeom.MatrixMulInv2(F0.Matrix, PGeom.MatrixMul(mr, F1.Matrix))); }
private void ExpandFaces() { PFace[] CFaces = new PFace[MaxNVert]; int NRefl = Group.Length; int p, q = BaseFaces.Length; for (int i = 0; i < q; i++) { BaseFaces[i].Id = i; CFaces[i] = new PFace(BaseFaces[i]); } for (p = 0; p < q; p++) { foreach (double [] G in Group) { double[] v = PGeom.ApplyTwist(G, CFaces[p].Pole); int j; for (j = 0; j < q; j++) { if (PGeom.VertEqual(v, CFaces[j].Pole)) { double[,] mf = PGeom.ApplyTwist(G, CFaces[p].Matrix); CFaces[p].Base.AddSMatrix(mf, CFaces[j].Matrix); break; } } if (j == q) { if (q == MaxNVert) { throw new Exception("Too many vertices"); } CFaces[q] = new PFace(CFaces[p], G); q++; } } } Faces = new PFace[q]; for (int i = 0; i < q; i++) { Faces[i] = CFaces[i]; Faces[i].Id = i; } foreach (PBaseFace BF in BaseFaces) { BF.CloseSMatrixSet(); } }
internal void InitPuzzle(Puzzle cube) { Cube = cube; int dim = Cube.Str.Dim; NF = Cube.Str.Faces.Length; NStk = Cube.Str.NStickers; SetColorsArray(null); StFaces = new StkMesh[NF]; FPoles = new double[NF][]; Stks = new StkMesh[NStk]; BPln = new bool[NF]; int[] vn = new int[100000 * 4]; lVN = 0; double[][][] FFPoles = new double[NF][][]; for (int i = 0; i < NF; i++) { PFace F = Cube.Str.Faces[i]; StFaces[i] = new StkMesh(F.Base.FaceMesh, i, F.Matrix); FPoles[i] = F.Pole; int fstk = F.FirstSticker; for (int j = 0; j < F.Base.NStickers; j++) { Stks[fstk + j] = new StkMesh(F.Base.StickerMesh[j], i, F.Matrix); Stks[fstk + j].FCtr = F.Pole; } double[][] baseFFP = F.Base.FPoles; FFPoles[i] = new double[baseFFP.Length][]; for (int j = 0; j < baseFFP.Length; j++) { FFPoles[i][j] = PGeom.ApplyMatrix(F.Matrix, baseFFP[j]); } } for (int i = 0; i < NF; i++) { StFaces[i].SetCoord(1, 1); } for (int i = 1; i < NF; i++) { for (int j = 0; j < i; j++) { double[][] pi = FFPoles[i], pj = FFPoles[j]; foreach (double[] vi in pi) { foreach (double[] vj in pj) { if (PtEq(vi, vj, dim)) { goto _1; } } } continue; _1: StkMesh Fi = StFaces[i], Fj = StFaces[j]; float[] fpi = Fi.Coords, fpj = Fj.Coords; for (int i1 = 0; i1 < fpi.Length; i1 += dim) { for (int j1 = 0; j1 < fpj.Length; j1 += dim) { if (PtEq(fpi, i1, fpj, j1, dim)) { vn[lVN++] = i; vn[lVN++] = i1; vn[lVN++] = j; vn[lVN++] = j1; break; } } } } } VertNetwork = new int[lVN]; Buffer.BlockCopy(vn, 0, VertNetwork, 0, lVN * sizeof(int)); }
internal PFace(PFace src, double[] tw) { Base = src.Base; Pole = PGeom.ApplyTwist(tw, src.Pole); Matrix = PGeom.ApplyTwist(tw, src.Matrix); }