I have 2 images I am placing on top of a 1080X1920 canvas.
One is a rectangle that is 800x400 and it is sitting on the 1080X1920 canvas with top left coordinates of x=140 and y=1200
Then I have another image that is the same size of the canvas 1080X1920, but also has a rectangle on it at the exact same coordinates as the first rectangle. I am overlaying this 1080X1920 image at x=0 and y=0 on the canvas so that the rectangle already in this image lines up perfectly with the rectangle that is already placed on the canvas.
My problem is, I need to apply a rotation to both of these and the black and red rectangles need to match up in positioning AFTER the rotation is applied. Could be any rotation, but let's say it is a 15 degree rotation.
When each element is placed on the canvas and then the 15 degree rotation is applied, the rectangles no longer align because of the difference in image size and the offset in rotation as they both rotate around the center point which looks to be my only option in this case.
So I am hoping to sort out a formula I can use that would rectify the positioning of the 1080X1920 image so that the object already embedded in that image lines up with separately overlaid image.
There are of course other ways to deal with this problem, but right now, they would make things quite a bit more difficult, so I wanted to see if this was possible to calculate first.
I have tried several ways to calculate this, but am not super mathematically proficient, so I am grasping at straws at best.
Oh and because I am not extremely mathematically proficient, any dumbing-down of mathematical terms is appreciated. ;)
Oh and possibly this post answers this question, but I can't wrap my head around whether or not it does, so if someone can let me know if it does, I will try harder to understand and apply it to my particular case.
How to recalculate the coordinates of a point after scaling and rotation?
CodePudding user response:
Any rotation is done around a "center of rotation". You don't tell the centers you use, but they can be:
- Center of the canvas.
- Center of each image (middle point of its four corners),
- Some corner.
- Any other point.
If both rotations are not the same, then there's not possible match.
It seems you use the center of each image. Then, to match the second rectangle to the first one, after you rotate the first image you must do in this order:
- Translate the second image so its center of rotation is exactly the same as the center of rotation of the first image. The vector of translation is the coordinates difference for X,Y centers.
- Rotate the second image with the same angle as the first image rotation.
CodePudding user response:
This boils down to tracking where the original (0,0) points are on the two images after rotation.
Let's define the problem a bit cleaner:
red.png
: 800x400black.png
: 1080X1920- rotate both by 15° (or θ = 15 * π/180) with
rotate
filter (assuming the actual values are within -90° and 90°) - how to place a rotated red.png on rotated black.png at the ORIGINAL top-left coordinates (x=140,y=120)
Consider 2 FFmpeg rotation commands:
ffmpeg red.png -vf rotate=15*PI/180:ow=hypot(iw\\,ih):oh=ow -frames:v 1 red_rotated.png
ffmpeg black.png -vf rotate=15*PI/180 -frames:v 1 black_rotated.png
Note that red_rotated.png
is enlarged to inscribe the red rectangle while black_rotated.png
maintains the same size. Now, the question is "where are the original top-left corner now?"
red_rotated.png
:
0 < θ < π/2
cases:(xr,yr) = (h sin(θ), 0)
-π/2 < θ < 0
cases:(xr,yr) = (0, w sin(θ))
black_rotated.png
: Same as red_rotated.png
but now cropped to the original size
- new size:
ow = w cos(θ) h sin(|θ|)
,oh = w sin(|θ|) h cos(θ)
- size delta:
dw = (ow - w)/2
,dh = (oh - h)/2
0 < θ < π/2
cases:(xb, yb) = (h sin(-θ) - dw, -dh)
-π/2 < θ < 0
cases:(xb, yb) = (-dw, w sin(θ) - dh)
Now, where is the insertion coordinate (x,y) = (140,120) on black_rotated.png
:
- rotate wrt the original corner:
(x1,y1) = (x cos(θ) - y sin(θ), x sin(θ) y cos(θ)
- shift wrt the new black corner:
(x2,y2) = (x1 xb, y1 yb)
- shift wrt the new red corner:
(x3,y3) = (x2 - xr, y2 - yr)
Accordingly overlaying red_rotated.png
with the offset (x3,y3)
onto black_rotated.png
should get you the results you want.
Disclaimer: I have not verified my math, but this is should be a good starting point.