Affine transform given 4 points - math

How can I get a 3x3 matrix representing all the transformations (scale,rotation) to apply to an image drawn on a canvas given 4 points x1,y1...x4,y4 representing the ROI(sub-image) that I want to zoom and rotate on?
The first coordinates x1,y1 should be transformed to the top left corner(0,0) of the canvas and x2,y2 to the bottom right corner of the canvas(canvas.width, canvas.height).
Thank you very much for your help!

Related

How to detect whether a circle and a polygon overlap?

I am implementing a function that can detect whether a circle and a polygon are overlapping or not.
I have all the points of the polygon and I know the center points and radius of the circle.
There I check two scenarios:
polygon vertices are inside the circle
circle center is inside the polygon
But there are other scenarios in which a circle and a polygon are overlapping, as shown in the attached image. Can anyone suggest validation for finding the intersection?
Here is a possible approach.
If one of the polygon vertices is inside the circle, there is overlap.
If the the circle center is inside the polygon, they overlap. Note that this test is not trivial for non-convex shape. For example consider a polygon similar to a thin spiral.
Otherwise, for every edge (a,b) of the polygon:
Find p, the projection of the circle center to the line (a,b).
If the distance of p to the circle center is larger than the radius, there is no overlap for this edge.
Otherwise, if p is between a and b (so p_x between a_x and b_x, and also p_y between a_y and b_y, to include the case of horizontal and vertical edges), then there is overlap for this edge, otherwise not.

Rotating a polygon so a specific side is on the bottom

I'm trying to find the angle it would take for me to rotate a polygon so that a specific side is completely horizontal and on the bottom.
For example, a shape like this:
Needs to be rotated so the side with the red square on it is on the bottom and completely horizontal, like this:
So far I've tried several approaches but all end up having strange edge cases where the angle is incorrect.
If you have coordinates of two vertices of this edge (x1,y1) and (x2,y2) in counterclockwise order, then rotation angle is
RotAngle = atan2 (y2-y1, x2-x1)

Libgdx - Keeping an object at certain distance and direction from other object

So let's say I have 2 objects. One with the sprite of a circle, other with the sprite of triangle.
My triangle object is set to the position of mouse in every step of the game, while circle is either standing in place or just moving in its own way, whatever.
What I want to do is to have the TRIANGLE move around the circle, but not on it's own, rather on the way your cursor is positioned.
So basically, calculate degree between circle's center and triangle's center. Whenever they are far from each other I just set triangle position to mouse position, BUT when you hover your mouse too close (past some X distance) you can't get any closer (the TRIANGLE is then positioned at maximum that X distance in the direction from circle center to mouse point)
I'll add a picture and hopefully you can get what I mean.
https://dl.dropboxusercontent.com/u/23334107/help2.png
Steps:
1. Calculate the distance between the cursor and the center of the circle. If it is more than the 'limit' then set the triangle's position to the cursor's position and skip to step 4.
2. Obtain the angle formed between the center of the circle and the cursor.
3. Calculate the new Cartesian coordinates (x, y) of the triangle based of off the polar coordinates we have now (angle and radius). The radius will be set to the limit of the circle before we calculate x and y, because we want the triangle to be prevented from entering this limit.
4. Rotate the image of the triangle to 1.5708-angle where angle was found in step 2. (1.5708, or pi/2, in radians is equivalent to 90°)
Details:
1. The distance between two points (x1, y1) and (x2, y2) is sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))
2. The angle (in radians) can be calculated with
double angle = Math.atan2(circleY-cursorY, cursorX-circleX);
The seemingly mistaken difference in order of circleY-cursorY and cursorX-circleX is an artefact of the coordinate system in most programming languages. (The y coordinate increases downwards instead of upwards, as it does in mathematics, while the x coordinate increases in concord with math - to the right.)
3. To convert polar coordinates to Cartesian coordinates use these conversions:
triangle.setX( cos(angle)*limit );
triangle.setY( sin(angle)*limit );
where limit is the distance you want the triangle to remain from the circle.
4. In order to get your triangle to 'face' the circle (as you illustrated), you have to rotate it using the libgdx Sprite function setRotation. It will rotate around the point set with setOrigin.
Now, you have to rotate by 1.5708-angle – this is because of further differences between angles in mathematics and angles in programming! The atan2 function returns the angle as measured mathematically, with 0° at three o'clock and increasing counterclockwise. The setRotation function (as far as I can tell) has 0° at twelve o'clock and increases clockwise. Also, we have to convert from radians to degrees. In short, this should work, but I haven't tested it:
triangle.setRotation(Math.toDegrees(1.4708-angle));
Hope this helps!

Get smallest bounding box for a polygon that is large enough despite orientation

I am currently getting the bounding box for my polygon by getting the min/max x and min/max y of the points, but when rotating the polygon the bounding box is too small to fit the rotated polygon. See the illustration for clarification:
This:
Turns into this:
How would I get the bounding box that is big enough to contain any rotated state?
If I understand the problem correctly, this is really trivial.
The point furthest away from the center will always be a vertex. So find the vertex with the maximum distance from the center, and make the box large enough to fit the polygon when that vertex is facing straight up, down, left and right:
Find the vertex furthest away from the center, and let d denote its distance from the center.
The polygon will always fit in the box 2d × 2d.

Math Problem: Getting Coordinates From Position And Angle

let me begin by stating that's i'm dreadful at math.
i'm attempting to reposition and rotate a rectangle. however, i need to rotate the rectangle from a point that is not 0,0 but according to how far its coordinates has shifted. i'm sure that doesn't make much sense, so i've made some sketches to help explain what i need.
the image above shows 3 stages of the red rectangle moving from 0% to 100%. the red rectangle's X and Y coordinates (top left of the red rectangle) only moves a percentage of the blue rectangle's height.
the red rectangle can rotate. focusing only on the middle example ("Distance -50%") from above, where the red rectangle is repositioned at -50 of the blue rectangle's height, its new angle in the above image is now -45º. it has been rotated from its 0, 0 point.
now, my problem is that i want its rotational point to reflect its position.
the red and blue rectangles are the same size, but have opposite widths and heights. since the red rectangle's 0,0 coordinates are now -50% of the blue rectangle's height, and since they have opposite widths and heights, i want the rotational point to be 50% of the red rectangle's width (or 50% of the blue rectangle's height, which is the same thing).
rather than specifically telling the red rectangle to rotate at 50% of its width, in order to do what i want, i need to emulate doing so by using a formula that will position the red rectangle's X and Y coordinates so that its rotational point reflects its position.
Here's an illustrated solution to your problem:
I don't exactly understand what you need, but it seems that a procedure to rotate a rectangle around an arbitrary point may help.
Suppose we want to rotate a point (x,y) d radians around the origin (0,0). The formula for the location of the rotated point is:
x' = x*cos(d) - y*sin(d)
y' = x*sin(d) + y*cos(d)
Now we don't want to rotate around the origin, but around a given point (a,b). What we do is first move the origin to (a,b), then apply the rotation formula above, and then move the origin back to (0,0).
x' = (x-a)*cos(d) - (y-b)*sin(d) + a
y' = (x-a)*sin(d) + (y-b)*cos(d) + b
This is your formula for rotating a point (x,y) d radians around the point (a,b).
For your problem (a,b) would be the point halfway on the right side of the blue rectangle, and (x,y) would be every corner of the red rectangle. The formula gives (x',y') for the coordinates of the corners of rotated red rectangle.
It's quite simple really.
1. Let's settle on your point you want to rotate the rectangle about, i.e. the point of rotation (RP) which does not move when you swivel your rectangle around. Let's assume that the point is represented by the diamond in the figure below.
2. Translate the 4 points so that RP is at (0,0). Suppose the coordinates of that point is (RPx,RPy), therefore subtract all 4 corners of the rectangle by those coordinates.
3. Rotate the points with a rotation matrix (which rotates a point anticlockwise around the origin through some angle which is now the point of rotation thanks to the previous translation):
The following figure shows the rectangle rotated by 45° anticlockwise.
4. Translate the rectangle back (by adding RP to all 4 points):
I assume this is what you want :)
It seems like you could avoid a more complex rotation by more crafty positioning initially? For example, in the last example, position the red box at "-25% Blue Height" and "-25% Red Height" -- if I follow your referencing scheme -- then perform the rotation you want.
If you know the origin O and a point P on the side of rotated rectangle, you can calculate the vector between the two:
(source: equationsheet.com)
You can get the angle between the vector and the x-axis by taking the dot product with this vector:
(source: equationsheet.com)
Given this, you can transform any point on the rectangle by multiplying it by a rotation matrix:
(source: equationsheet.com)

Resources