Pas possible avec CGAffineTransform. Une transformation affine peut toujours être décomposé en translations, rotations, de cisaillement et de mise à l'échelle. Ils ont tous la carte des parallélogrammes en parallélogrammes, qui votre transformation n'a pas.
Pour votre transformation, il peut être fait en deux étapes. De convertir la place dans un trapèze.
p1-----p2 p1-----p2
| | --> | \
p3-----p4 p3--------p4'
Un autre pour la direction verticale. Un naïf règle de transformation est
y - c
x' = (x - p1.x) * -------- + p1.x
p1.y - c
y' = y
où c est l'abscisse du point d'intersection des lignes reliant p1 et p3 et p2 et p4.
Maintenant, remarquez le x*y facteur dans la transformation. Ceci indique qu'une telle transformation n'est pas linéaire. Par conséquent, CATransform3D ne peut effectuer qu'une transformation 2D soit.
Cependant, le vecteur
[x, y, z, w=1]
seront convertis à la réalité de vecteur 3D
(x/w, y/w, z/w)
avant la projection, si CA suit d'habitude 3D calculer les règles graphiques, de sorte que vous pouvez "tricher" en utilisant la transformation
[ P . . Q ] [ x ] [ x' ]
[ . R . S ] [ y ] = [ y' ]
[ . . 1 . ] [ z ] [ z' ]
[ . T . U ] [ 1 ] [ w' ]
avec appropriée, P, Q, R, S, T, U, qui mappe les 4 points de la lieux. (6 unique coordonne et 6 variables devraient avoir exactement 1 solution de la plupart des cas.)
Lorsque vous avez trouvé ces 6 constantes, vous pouvez créer un CATransform3D. Avis de la définition de la structure est
struct CATransform3D
{
CGFloat m11, m12, m13, m14;
CGFloat m21, m22, m23, m24;
CGFloat m31, m32, m33, m34;
CGFloat m41, m42, m43, m44;
};
typedef struct CATransform3D CATransform3D;
Vous pouvez directement modifier les éléments de la matrice, au lieu de compter sur la CATransform3DMake fonctions. (Vous devrez peut-être effectuer une transposition grâce à la convention de l'utilisation de la ligne ou de la colonne des vecteurs.)
Pour obtenir la transformation pour convertir un rectangle ((X, Y), (W, H)) pour tout quadrilatère ((x1a) y1a), (x2a, y2a); (x3a, y3a), (x4a, y4a)), l'utilisation de cette fonction (vous pouvez avoir besoin d'une transposition):
function compute_transform_matrix(X, Y, W, H, x1a, y1a, x2a, y2a, x3a, y3a, x4a, y4a) {
var y21 = y2a - y1a,
y32 = y3a - y2a,
y43 = y4a - y3a,
y14 = y1a - y4a,
y31 = y3a - y1a,
y42 = y4a - y2a;
var a = -H*(x2a*x3a*y14 + x2a*x4a*y31 - x1a*x4a*y32 + x1a*x3a*y42);
var b = W*(x2a*x3a*y14 + x3a*x4a*y21 + x1a*x4a*y32 + x1a*x2a*y43);
var c = H*X*(x2a*x3a*y14 + x2a*x4a*y31 - x1a*x4a*y32 + x1a*x3a*y42) - H*W*x1a*(x4a*y32 - x3a*y42 + x2a*y43) - W*Y*(x2a*x3a*y14 + x3a*x4a*y21 + x1a*x4a*y32 + x1a*x2a*y43);
var d = H*(-x4a*y21*y3a + x2a*y1a*y43 - x1a*y2a*y43 - x3a*y1a*y4a + x3a*y2a*y4a);
var e = W*(x4a*y2a*y31 - x3a*y1a*y42 - x2a*y31*y4a + x1a*y3a*y42);
var f = -(W*(x4a*(Y*y2a*y31 + H*y1a*y32) - x3a*(H + Y)*y1a*y42 + H*x2a*y1a*y43 + x2a*Y*(y1a - y3a)*y4a + x1a*Y*y3a*(-y2a + y4a)) - H*X*(x4a*y21*y3a - x2a*y1a*y43 + x3a*(y1a - y2a)*y4a + x1a*y2a*(-y3a + y4a)));
var g = H*(x3a*y21 - x4a*y21 + (-x1a + x2a)*y43);
var h = W*(-x2a*y31 + x4a*y31 + (x1a - x3a)*y42);
var i = W*Y*(x2a*y31 - x4a*y31 - x1a*y42 + x3a*y42) + H*(X*(-(x3a*y21) + x4a*y21 + x1a*y43 - x2a*y43) + W*(-(x3a*y2a) + x4a*y2a + x2a*y3a - x4a*y3a - x2a*y4a + x3a*y4a));
return [[a,b,0,c],[d,e,0,f],[0,0,1,0],[g,h,0,i]];
}