Reputation: 6192
I have a 3X3 transform matrix that's the output of a homography transform.
I want to rotate and stretch a div according to this matrix but it looks like css transform either receives a 4X4 matrix or a 2X3 matrix.
I tried to convert the 3X3 matrix by adding zeros and a one like here but it looks completley wrong (it's either making the div rotated by 90 degrees or if I do a transpose, too small).
How can I transform that 3X3 matrix such that css' transform will work correctly?
Upvotes: 3
Views: 2989
Reputation: 2140
Here some thougths that will propably help you:
There are a few possibilities concerning the matrix you recive:
The matrix is a 2D transformation matrix: In this case the matrix extension you do wil fail, because the matrix layout will look like this:
[x1, x2, tx]
[y1, y2, ty]
[0 , 0 , 1 ]
An extension would then look like this for a 4x4 matrix assuming that X and Y-axis dont change:
[x1, x2, 0, tx]
[y1, y2, 0, ty]
[0 , 0 , 1, 0 ]
[0 , 0 , 0, 1 ]
But since css is using a 2x3 matrix the last row is implied. So you can add them like this: transform: matrix(x1,y1,x2,y2,tx,ty);
(see https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix)
The matrix is a 3D rotation matrix: In this case the matrix extension you do wil fail, because the matrix layout will look like this:
[x1, x2, x3]
[y1, y2, y3]
[z1, z2, z3]
An extension would then look like this for a 4x4 matrix: (see the link in your question)
[x1, x2, x3, 0]
[y1, y2, y3, 0]
[z3, z3, z3, 0]
[0 , 0 , 0 , 1]
You can add them like this: transform: matrix(x1,y1,z1,0, x2,y2,z2,0, x3,y3,z3,0, 0,0,0,1);
(see https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix)
Last possibility: the Matrix is a projective one. No clue hot to handle this..
If i had to take a guess: By looking at this example (from the link you provided) I would say this is a 2D transformation matrix
BE AWARE: the jsfeat lib has a row-major order, but css needs a column-major order!
var affine_kernel = new jsfeat.motion_model.affine2d();
var affine_transform = new jsfeat.matrix_t(3, 3, jsfeat.F32_t | jsfeat.C1_t);
var count = 33;
var from = [];
var to = [];
for(var i = 0; i < count; ++i) {
from[i] = { "x":Math.random()*320, "y":Math.random()*240 };
to[i] = { "x":from[i].x + 5, "y":from[i].y+5 };
}
affine_kernel.run(from, to, affine_transform, count);
var a = [...affine_transform.data.subarray(0 , 6)];
b = [
0.08420821279287338,
-0.03247755020856857,
14.28314018249511,
-0.009080140851438,
0.11894367635250,
7.15110540390014,
-0.00034110905835,
-0.01147077046,
1
];
window.addEventListener('load', function(){
var elem = document.getElementById('to-transform');
elem.style.transform = 'matrix('+a[0]+','+a[3]+','+a[1]+','+a[4]+','+a[2]+','+a[5]+')';
var mat = [b[0],b[3],0,b[6], b[1],b[4],0,b[7], 0,0,1,0, b[2],b[5],0,b[8] ]
var elem1 = document.getElementById('to-transform2');
elem1.style.transform = 'matrix3d('+mat.join(',')+')';
})
.container {
width:200px;
height:200px;
background: #aaa;
position:relative;
float:left;
margin-right:10px;
}
.to-transform {
width:100px;
height:100px;
position:absolute;
background: #a00;
text-align: center;
line-height: 92px;
}
<script type="text/javascript" src="https://inspirit.github.io/jsfeat/js/jsfeat-min.js"></script>
<div class="container">
<div id="to-transform" class="to-transform">to-transform</div>
</div>
<div class="container">
<div id="to-transform2" class="to-transform">to-transform2</div>
</div>
Upvotes: 2