Finding a set of 9 integers that minimize an error function
I have an algorithm that takes a 3d triangle PMN(which is constructed from running a function that converts per-vertex UV coordinates to a PMN triangle) and P' which is a randomly chosen 3D point that is outside the plane of PMN and constructs two new 3D points (M', N') where the new points correspond to the same(with a small error margin) UV coordinates
My goal is to construct a PMN triangle such that every value is very close to a whole number eg: (27.007, -26.995, 73.997), (-155.005, 74.001, -4.0041) (31.992, -195.9993, -15.00081) would be valid as the error margin here is acceptable
A bruteforce approach where i choose a random P' between some range and then compare each value of the resulting M' and N' against an epsilon is only feasible when epsilon is quite large(using an epsilon of 0.005 and P' range of -200 to 200 takes about 100ms to compute on average) which is acceptable only if the input is a small amount of triangles
I am looking for an algorithm that would allow me to compute P', M', N' with a small epsilon(anything below 0.01 would be considered acceptable) in a reasonable time as the bruteforce approach is extremely slow as epsilon gets smaller(like i mentioned above it takes ages to run even if the epsilon is 0.05)
My error function is defined as: private TriangleUV getError(TriangleUV a, TriangleUV b) { return new TriangleUV( abs(a.u1() - b.u1()), abs(a.u2() - b.u2()), abs(a.u3() - b.u3()), abs(a.v1() - b.v1()), abs(a.v2() - b.v2()), abs(a.v3() - b.v3()) ); } where the first input is the original triangle UV coordinate and the second input is the UV coordinate constructed from pPrime, mPrime, nPrime
PMN to UV function which implements the algorithm described here: https://gamedev.stackexchange.com/q/185427/147479 ``` public TriangleUV computeUVFromPMN(int face, Vector3D p, Vector3D m, Vector3D n) {
float[] u = new float[3];
float[] v = new float[3];
int faceA = faceIndicesA[face];
int faceB = faceIndicesB[face];
int faceC = faceIndicesC[face];
Vector3D a = new Vector3D(verticesXCoordinate[faceA], verticesYCoordinate[faceA], verticesZCoordinate[faceA]);
Vector3D b = new Vector3D(verticesXCoordinate[faceB], verticesYCoordinate[faceB], verticesZCoordinate[faceB]);
Vector3D c = new Vector3D(verticesXCoordinate[faceC], verticesYCoordinate[faceC], verticesZCoordinate[faceC]);
final Vector3D PM = m.subtract(p);
final Vector3D PN = n.subtract(p);
final Vector3D PA = a.subtract(p);
final Vector3D PB = b.subtract(p);
final Vector3D PC = c.subtract(p);
final Vector3D PMxPN = PM.crossProduct(PN);
final Vector3D U = PN.crossProduct(PMxPN);
double Mu = 1.0F / U.dotProduct(PM);
double uA = U.dotProduct(PA) * Mu; /* 1st U coordinate (for vertex A) */
double uB = U.dotProduct(PB) * Mu; /* 2nd U coordinate (for vertex B) */
double uC = U.dotProduct(PC) * Mu; /* 3rd U coordinate (for vertex C) */
final Vector3D V = PM.crossProduct(PMxPN);
double Mv = 1.0 / V.dotProduct(PN);
double vA = V.dotProduct(PA) * Mv; /* 1st V coordinate (for vertex A) */
double vB = V.dotProduct(PB) * Mv; /* 2nd V coordinate (for vertex B) */
double vC = V. 835