
ClearAll["Global`*"]


example = {
 x0->64000000000000000000000000000000,   y0->  -20000000000000000000000000000000, z0->100000000000000000000000000000000,
 x1->-109000000000000000000000000000000, y1->   38000000000000000000000000000000, z1-> 2066632666984436159899233718861,
 x2->-25000000000000000000000000000000,  y2->   51000000000000000000000000000000, z2-> 485312770651928720409074796169,
 x3->78000000000000000000000000000000,   y3->   62000000000000000000000000000000, z3-> 822752145561371645579125478661,
 x4->-x3,y4->-y3,z4->z3,
 x5->-x2,y5->-y2,z5->z2,
 x6->-x1,y6->-y1,z6->z1,
 x7->-x0,y7->-y0,z7->z0
}

U = {
  {x0,y0,z0},
  {x1,y1,z1},
  {x2,y2,z2},
  {x3,y3,z3}
};

(* symmetry map: 180° rotation about Z *)
RZ[A_] := {-A[[1]], -A[[2]], A[[3]]};

(*Here is the golden pup tent.  Technically we just use the
first four relations and symmetry.*)
V={U[[1]],U[[2]],U[[3]],U[[4]],RZ[U[[4]]],RZ[U[[3]]],RZ[U[[2]]],RZ[U[[1]]]}//.example



(* Triangulation (0-based indices) *)

triangles = {
   {3,5,6}, {3,2,5}, {3,6,4}, {3,0,2}, {3,4,1},
   {3,1,0}, {5,0,6}, {5,2,4}, {5,4,7}, {5,7,0},
   {6,7,4}, {6,0,1}, {6,1,7}, {2,1,4}, {2,0,7}, {2,7,1}
  };


Print["---------------FLATNESS-------------------------------------"];

(*This computes the jacobian matrix for symmetric variations of
  pup tents, evaluated along the golden valley. We are using
  we choose.  The ANGLE variable encodes this choice.  The
  options are {0,1,2} or {0,2,3}, or {0,1,3} or {1,2,3}.
  We use ANGLE = {0,1,2}, as in the paper*)



(* Angle at vertex i in triangle {i,j,k} *)
angleAt[i_, j_, k_] := Module[
  {vi, vj, vk, u, w, uu, ww, uw, c},
  vi = V[[i + 1]]; 
  vj = V[[j + 1]]; 
  vk = V[[k + 1]];
  u  = vj - vi;
  w  = vk - vi;
  uu = Dot[u, u];
  ww = Dot[w, w];
  uw = Dot[u, w];
  c  = uw/(Sqrt[uu] Sqrt[ww]);
  ArcCos[c]
]

(* Angle contribution of a triangle to vertex v *)
angleInTri[{i_, j_, k_}, v_] := 
  If[v == i, angleAt[i, j, k],
    If[v == j, angleAt[j, k, i],
      If[v == k, angleAt[k, i, j], 0]
    ]
  ];

(* Cone angles *)
ConeAngle[v_] := Module[{sum = 0, t},
  For[t = 1, t <= 16, t++,
    sum = sum + angleInTri[triangles[[t]], v];
  ];
sum
];


(*Here is the flatness*)

Print[V];

Print[Table[N[2 Pi-ConeAngle[j],50],{j,0,2}]];


(**The jacobian*)

(*This lists the vectors symbolically*)
V = {
  {x0,y0,z0},
  {x1,y1,z1},
  {x2,y2,z2},
  {x3,y3,z3},
  {x4,y4,z4},
  {x5,y5,z5},
  {x6,y6,z6},
  {x7,y7,z7}
};




(*Here is the Jacobian. We want symmetric variations.
The symmetry is (x,y,z) <-> (-x,-y,z). The convention
is that we just vary the first 4 points.*)

J0[k_]:=D[ConeAngle[k],z0]+D[ConeAngle[k],z7];
J1[k_]:=D[ConeAngle[k],z1]+D[ConeAngle[k],z6];
J2[k_]:=D[ConeAngle[k],z2]+D[ConeAngle[k],z5];
JJ0  := Table[J0[k],  {k,0,2}];
JJ1  := Table[J1[k],  {k,0,2}];
JJ2  := Table[J2[k],  {k,0,2}];

JJsym = {JJ0, JJ1, JJ2};

JAC = {JJ0,JJ1,JJ2}//.example;
JAC=JAC Power[10,32];
Print[MatrixForm[N[JAC,16]]];


(**********************************************************************)

