Я не знаю какой-либо стандартной реализации Java, но для меня работает следующий код (с использованием LibGDX для предоставления операций с точками и матрицами). Для получения матрицы преобразования я использую getProjectionMatrix
; если у меня есть это, я могу преобразовать точки, используя что-то похожее на transformPoints
выше. Вы могли бы называть transformPoints
для каждого из «квадратных пикселей» в вашем первом изображении и получать углы для соответствующего «проецируемого пикселя» во втором изображении. Это медленное, но, к сожалению, никто не заставляет вас not использовать OpenGL ...
/**
* Transforms all points in a polygon using a 3x3 projection matrix.
*
* @param t
* the 3x3 transform matrix
* @param points
* the points to transform. Coordinates will be overwritten
*/
public static void transformPoints(Matrix3 t, Vector2... points) {
Vector3 v3 = new Vector3();
for (Vector2 v : points) {
v3.set(v.x, v.y, 1);
v3.mul(t);
v.set(v3.x / v3.z, v3.y / v3.z);
}
}
private static Matrix3 mapBasisToImage(Vector2[] v) {
// solve (v1 v2 v3) * <a b c> = v4 using <a b c> = (v1 v2 v3)^-1 * v4
Matrix3 v123 = new Matrix3(new float[] { v[0].x, v[0].y, 1, v[1].x,
v[1].y, 1, v[2].x, v[2].y, 1 });
Vector3 v4 = new Vector3(new float[] { v[3].x, v[3].y, 1 });
float[] M = v123.val.clone();
v4.mul(v123.inv());
// scale by solutions
for (int i = 0; i < 3; i++) {
M[i + 0] *= v4.x;
M[i + 3] *= v4.y;
M[i + 6] *= v4.z;
}
Matrix3 bti = new Matrix3(M);
return bti;
}
/**
* Calculates a projection matrix from two corresponding sets of four
* non-collinear 2d vertices. Notice that "view" and "world" are actually
* interchangeable. Use sparingly: several intermediate matrices are
* required, and performance may suffer if called in a tight loop.
*
* @param view
* four points in the "view" (a camera pointed at the world,
* probably with some kind of perspective distortion)
* @param world
* four corresponding points in the "world" (where distances and
* angles are correct)
* @return a 3d projection that can be used to transform any view-based 2d
* vector into 'real space', and inverted to undo the process.
* @see <a href="http://jsfiddle.net/dFrHS/1/">this example</a>, referenced
* and described an excellent @see <a
* href="http://math.stackexchange.com/questions/296794/">
* math.stackexchange.com answer</a>.
*/
public static Matrix3 getProjectionMatrix(Vector2[] view, Vector2[] world) {
Matrix3 A = mapBasisToImage(view);
Matrix3 B = mapBasisToImage(world);
// combined - translates any vector from v-space to w-space
return B.mul(A.inv());
}
Преобразование его в стандартные классы Java должно быть простым (хотя стандартная Java не имеет Point3D, вам просто нужны x, y и z, и есть много простых библиотек инверсии матрицы и amp;).