A note on computation of KG error:
There seems to be a small ambiguity in the interpretation of the KG error (for detail see Karni, Gotsman: "Compression of soft body animation sequences"). Therefore we are presenting a piece of source code in C# which demonstrates how the KG error should be computed. Please note that this interpretation is a consensus of several researchers in the field of dynamic mesh compression.
int pointCount = ((UnstrGrid)input1[0]).Points.Count; int frameCount = input1.Count; double[,] means = new double[frameCount, 3]; for (int i = 0; i < pointCount; i++) { for (int j = 0; j < frameCount; j++) { TriangleMesh mesh = (TriangleMesh)input1[j]; Point3D point = (Point3D)mesh.Points[i]; means[j, 0] += point.X; means[j, 1] += point.Y; means[j, 2] += point.Z; } } for (int i = 0; i < frameCount; i++) { means[i, 0] /= pointCount; means[i, 1] /= pointCount; means[i, 2] /= pointCount; } double s1 = 0; double s2 = 0; for (int i = 0; i < frameCount; i++) { UnstrGrid frame1 = (UnstrGrid)input1[i]; UnstrGrid frame2 = (UnstrGrid)input2[i]; UniformDataArray points1 = frame1.Points; UniformDataArray points2 = frame2.Points; for (int j = 0; j < pointCount; j++) { Point3D p1 = (Point3D)points1[j]; Point3D p2 = (Point3D)points2[j]; s1 += (p1.X - p2.X) * (p1.X - p2.X); s1 += (p1.Y - p2.Y) * (p1.Y - p2.Y); s1 += (p1.Z - p2.Z) * (p1.Z - p2.Z); s2 += (p1.X - means[i, 0]) * (p1.X - means[i, 0]); s2 += (p1.Y - means[i, 1]) * (p1.Y - means[i, 1]); s2 += (p1.Z - means[i, 2]) * (p1.Z - means[i, 2]); } } result = new Scalar((Math.Sqrt(s1)/Math.Sqrt(s2))*100); SetOutput("KG error", result);
Although we are using some calls specific for the development environment we're using, we believe that the main procedure of error evaluation is clear and can be rewritten in any programming language without any ambiguities.