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)
Related
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.
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!
I have a cannon that fires a cannonball and smoke particle effect, i want the cannon ball to start at the end of the cannon, this i can do by adding the width of the cannon to its x position and adding the half the height to the cannon. This works fine when the cannon is unrotated but when i rotate the cannon its not in the correct position. This is what i use to try and rotate the vector.
Vector2 rotPos = cannon.position.tmp().add(cannon.bounds.width, cannon.bounds.height/2).rotate(cannon.angle);
How can i get a rotated vector that fires the cannon ball in the correct place. See image below.
UPDATE
I tried the below also, same result the ball is off to the left
Vector2 rotPos = world.CannonBody.getWorldVector( world.CannonBody.getPosition() );
The way that you've described the problem, you've solved it for only a single case. This really is just a math problem. Think about the direction you want to shoot, the barrel of the cannon, as the coordinates on a circle.
Since you know the angle, this is easy. Draw a circle with a dot in the center. Then draw a line from the center to the right edge. Then draw another line at a 45 degree angle up from the first line. Connect the two points on the edges with a straight line. You have a triangle now.
Lets call the 45 degree angle line 'r'. And we'll call the first line x, and the last line y.
You should have something that looks like this:
http://i.stack.imgur.com/MJNWZ.jpg
We know that sin(angleInRadians) = y/r. Doing a little algebra we can change this into r*sin(angleInRadians) = y
Boom, you have your y coordinate.
Almost the same thing: cos(angleInRadians) = x/r
So r*cos(angleInRadians) = x
There's your x coordinate.
The you can get the angle of a body directly from box2d, so that's easy. You just need to pick a value for 'r' that represents a correct radius for the circle that you're using to conceptualize the barrel of the cannon at a given angle. If the cannon rotates around the center of the circle, then r is the length of your cannon.
I had an issue which is similar to yours. Here's the question with an answer:
Android. How to move object in the direction it is facing (using Vector3 and Quaternion)
You need something like
translation.set(baseDirection).rot(modelInstance.transform).nor()
This is related to the arc drawn by HTML5 canvas "arcTo" function. I need to calculate the two tangent points of a circle with the radius R and two lines given by three points Q(x0,y0), P(x1,y1) and R(x2,y2).
The sketch explains the problem more. I need to find the tangent points A(xa,ya) and B(xb,yb). Note that the center of the circle is not given. Please help.
This is a question of solving a triangle with 2 known angles and one known side. Label the centre of the circle C, then the side you know is BC (or AC if you want). Angle PBC (CAP) is a right angle. The line CP bisects the angle RPQ.
Not all such triangles have a solution.
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)