This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Calculate Bounding box coordinates from a rotated rectangle, Picture inside.
I have a rotated rectangle,
So how do i calculate the size of axis-aligned bounding box for the rotated rectangle in 2D Coordinates?
Attach Image
http://img88.imageshack.us/img88/503/rotp.png
i know x, y, o (angle)
but how do i get a, b
Thank you
a = abs(x * sin(o)) + abs(y * cos(o))
b = abs(x * cos(o)) + abs(y * sin(o))
To construct an axis-aligned bounding box, one must find the extreme points of the rotated box. i.e.,
given a rectangle 'P', given by points P1=(0,0), P2=(x,0), P3(x,y), P4(0,y), rotated 'R' degrees; find minX, maxX, minY, maxY, such that the box [(minX,minY),(maxX,maxY)] completely bounds the rotated 'P'.
+-------P3'----+maxY
| / \ |
P4------P3 | / \ |
| | rotate | / P2'
| | => by 'R' => P4' /|
| | degrees | \ / |
P1------P2 | \ / |
| \ / |
+-----P1'------+minY
minX maxX
The values for the bounding box are the minimum/maximum of the components of the rotated points P1'..P4'; thus,
minX=min(P1'[x],P2'[x],P3'[x],P4'[x])
maxX=max(P1'[x],P2'[x],P3'[x],P4'[x])
minY=min(P1'[y],P2'[y],P3'[y],P4'[y])
maxY=max(P1'[y],P2'[y],P3'[y],P4'[y])
For a discussion of 2D rotations, see http://en.wikipedia.org/wiki/Transformation_matrix#Rotation
Well you didn't give a whole lot of detail. I'm assuming you know that the height and width of the rectangle will give you the area no matter the rotation. If you only have the x,y data points then you use the sqrt((x1-x1)^2 + (y1-y2)^2). To get the length of a side.
You clarified your question so if you have a rectangle and you know the angle from the top left corner is rotated away from the top so the left side looks like this.
/
/
a = sine(alpha)*width
b = cosine(alpha)*width
c = sine(alpha)*height
d = cosine(alpha)*height
width = a + d
height = b + c
Be sure you get the angle right it is kind of hard to clarify it on here. If you get the other angle then it will come out to
width = b + c
height = a + d
For the axis aligned box of the rotated rectangle, you find the minimum and maximum of each of the 4 rotated coordintates. The minX and minY becomes 1 corner and the maxX and maxY becomes the other corner.
Use [Heron's Formula Triangle Area Calculator]
s = (a + b + c) / 2 or 1/2 of the perimeter of the triangle
A = SquareRoot(s * (s - a) * (s - b) * (s - c))
Where
a=SquareRoot((X1-X2)^2+(Y1-Y2)^2) [Side 1 Length]
b=SquareRoot((X1-X3)^2+(Y1-Y3)^2) [Side 2 Length]
c=SquareRoot((X2-X3)^2+(Y2-Y3)^2) [Side 3 Length]
X1,Y1,X2,Y2,X3,Y3 are the coordinations of any three points (Corners)
RectangleArea=2*A
Or Direct without [Heron's Formula Triangle Area Calculator], sequence of points are important here.
P1----P2
| |
P3----P4
a=SquareRoot((X1-X2)^2+(Y1-Y2)^2) [Side 1 Length]
b=SquareRoot((X1-X3)^2+(Y1-Y3)^2) [Side 2 Length]
RectangleArea=a*b
Calculate the area of the original rectangle. Area doesn't change under rotation.
It's a bit complicated, but for a rectangle, Area = b * h = length * width.
Related
I use cropperjs to crop some image, I keep in database the result of getData method who return values in white on the picture.
{x, y, width, height, rotate}
My users can place points on the cropped image in the red space, is there a way to retrieve the coordinates of the point in the blue space?
The crop ratio is free so there is no relation between original image ratio and crop ratio and I don't have the original image size.
Thank you for your help
At first get coordinates in bounding box
bbx = redx + x
bby = redy + y
Now make rotation about bounding box center
bluex = bbcenterx + (bbx - bbcenterx) * Cos(rotate) + (bby - bbcentery) * Sin(rotate)
bluey = bbcentery - (bbx - bbcenterx) * Sin(rotate) + (bby - bbcentery) * Cos(rotate)
If you don't know bounding box size, but know initial picture width w and height h, you can calculate bounding box center
bbcenterx = (w * Abs(Sin(rotate)) + h * Abs(Cos(rotate))) / 2
bbcenterx = (w * Abs(Cos(rotate)) + h * Abs(Sin(rotate))) / 2
I have a set of evenly spaced point that forms a rectangle (sorry for the bad drawing, imagine all points are evenly spaced), and applying an angle, i want to go from left picture to right picture. The only point that does NOT move are the bottom left and the top right.
I guess i can deduce new locations of each point using tangent to get dx and dy. But i am not sur that i will end up with exactly what i want. And there may be a more elegent transformation to apply on each point ?
So we want to preserve two opposite vertices of rectangle and diagonal between them.
Let half-width of rectangle is w, half-height h, circle radius r. Let coordinate origin is at circle center.
Angle between diagonal and OX is
theta = atan(h/w)
After transformation angle between diagonal and low edge of new rectangle is
fi = alpha + theta
So we can find half-width of new rectangle
nw = r * cos(fi)
And coordinates of shifted vertex are
2*nw*cos(alpha) - w, -h - 2*nw*sin(alpha)
We want to find affine tranformation M that transform two vertices to the same points and the third vertex into coordinates above
|-w w w| |-w w 2*nw*cos(alpha) - w |
M * |-h h -h| = |-h h -h - 2*nw*sin(alpha)|
|1 1 1| |1 1 1|
To find M, we make inversion of the left matrix and multiply both sides by this inverse.
M = |nw*cos(alpha)/w w/h - nw*cos(alpha)/h 0|
|-nw*sin(alpha)/w 1 + nw*sin(alpha)/h 0|
|0 0 1|
Now we can transform all coordinates with this matrix and get rotated rectangle.
Example of coordinate transformation from my Delphi program generating picture below:
nX := Round(cx + x * cos(alpha)*nw/w + y * (w/h - cos(alpha)*nw / h));
nY := Round(cy - x * nw/w*sin(alpha) + y * (1 + nw/h * sin(alpha)));
i have some X/Y coordinates that represent the center of a circle somewhere in an image. From that circle, i want to compoute the mean of all the point contained inside the circle.
currently, i compute the mean of a square patche as follow, but a square is not relevent for the project. Ideally, i would like to do it only with numpy. but if it is not possible, i would concidere something else.
mean = np.mean(image[Y - margin : Y + margin, X - margin, X + margin])
As I understood,
YOU HAVE: (x,y) of the center of the circle
YOU WANT: mean of all the points contained in the circle
Since all the points on the right side should be equal to the number of points on the left side of the center, Wouldn't the mean be the same as the center of the circle !?
i found a solution where I compute all indexes contained in a centered disk.
I calculate the squarred euclidean distance of each X/Y coordinate of a squarre array.
I compare it to the squarred radius of the circle.
If it is superior, the point is not contained in the circle. Mark it as 0, 1 otherwise
I extract indexes where the array is equal to one (disk-shaped)
I center the computed indexes. To use them, i add the X/Y coordinate of a specific image point.
NOTE: I used the squarred euclidean distance because the square root function is monotonic (i.e constantly increasing). So, it saves compational power to keep with the squarred version.
radius = 4
size = 2 * radius + 1
radiusSquarred= radius**2
mask = np.zeros((size, size))
distance = lambda x, y: (x-radius)**2 + (y-radius)**2
for i in range(size):
for j in range (2 * radius+ 1):
if distance(i, j) <= radiusSquarred:
mask[i, j] = 1
index = np.where(mask == 1)
diskIndexes = (index[0] - radius, index[1] - radius)
X, Y = 100, 150
np.mean(image[diskIndexes[0] + Y, diskIndexes[1] + X])
I have an infinite grid of hexagons, defined by a cubic (x y z) coordinate system like so:
I also have a viewport -- a rectangular canvas where I will draw the hexagons.
My issue is this. Because the grid of hexagons is infinite in all directions, I can't feasibly draw all of them at once. Therefore, I need to draw all the hexagons that are in the viewport, and ONLY those hexagons.
This image summarizes what I want to do:
In this image, purple-colored hexagons are those I want to render, while white-colored hexagons are those I don't want to render. The black rectangle is hte viewport -- all the hexagons that intersect with it are to be drawn. How would I find which hexagons to render (IE their xyz coordinates)?
Some other info:
I have a function that can recall a hexagon tile and draw it centered at position(x,y) in the viewport, given its cubic xyz coordinates. Therefore, all I should need is the xyz coords of each rectangle to draw, and I can draw them. This might simplify the problem.
I have formulas to convert from cubic hexagon coordinates to x/y coordinates, and back. Given the above diagram, r/g/b being the axes for the cubic coords with the image above, x and y being the cartesian coordinates, and s being the length of a hexagon's edge...
y = 3/2 * s * b
b = 2/3 * y / s
x = sqrt(3) * s * ( b/2 + r)
x = - sqrt(3) * s * ( b/2 + g )
r = (sqrt(3)/3 * x - y/3 ) / s
g = -(sqrt(3)/3 * x + y/3 ) / s
r + b + g = 0
Let's X0, Y0 are coordinates of top left corner, RectWidth is rectangle width, HexWidth = s * Sqrt(3/2) is hexagon width.
Find center of the closest hexagon r0, g0, b0, HX0, HY0. (Rect corner lies in this hexagon, because hexagons are Voronoy diagram cells). Remember horizontal and vertical shift DX = X0 - HX0, DY = Y0 - HY0
Draw horizontal row of Ceil(RectWidth/HexWidth) hexagons, incrementing r coordinate, decrementing f, and keeping b the same, ROWINC=(1,-1,0).
Note that if DY > HexWidth/2, you need extra top row with initial coordinates shifted up (r0, g0-1, b0+1)
Shift starting point by L=(0, 1, -1) if the DX < 0, or by R=(1, 0, -1) otherwise. Draw another horizontal row with the same ROWINC
Shift row starting point by alternative way (L after R, R after L). Draw horizontal rows until bottom edge is reached.
Check whether extra row is needed in the bottom.
You can think of the rectangular box in terms of constraints on an axis.
In the diagram, the horizontal lines correspond to b and your constraints will be of the form somenumber ≤ b and b ≤ somenumber. For example the rectangle might be in the range 3 ≤ b ≤ 7.
The vertical lines are a little trickier, but they are a “diagonal” that corresponds to r-g. Your constraints will be of the form somenumber ≤ r-g and r-g ≤ somenumber. For example it might be the range -4 ≤ r-g ≤ 5.
Now you have two axes with constraints on them, and you can form a loop. The easiest thing will be to have the outer loop use b:
for (b = 3; b ≤ 7; b++) {
…
}
The inner loop is a little trickier, because that's the diagonal constraint. Since we know r+g+b=0, and we know the value of b from the outer loop, we can rewrite the two-variable constraint on r-g. Express r+g+b=0 as g=0-r-b. Now substitute into r-g and get r-(0-r-b). Simplify r-(0-r-b) to 2*r-b. Instead of -4 ≤ r-g we can say -4 ≤ 2*r-b or -4+b ≤ 2*r or (-4+b)/2 ≤ r. Similarly, we can rearrange r-g ≤ 5 to 2*r-b ≤ 5 to r ≤ (5+b)/2. This gives us our inner loop:
for (b = 3; b ≤ 7; b++) {
for (r = (-4+b)/2; r ≤ (5+b)/2; r++) {
g = 0-b-r;
…
}
}
The last bit is to generalize, replacing the constants 3,7,-4,5 with the actual bounds for your rectangle.
Imagine a circle. Imagine a pie. Imagine trying to return a bool that determines whether the provided parameters of X, Y are contained within one of those pie pieces.
What I know about the arc:
I have the CenterX, CenterY, Radius, StartingAngle, EndingAngle, StartingPoint (point on circumference), EndingPoint (point on circumference).
Given a coordinate of X,Y, I'd like to determine if this coordinate is contained anywhere within the pie slide.
Check:
The angle from the centerX,centerY through X,Y should be between start&endangle.
The distance from centerX,centerY to X,Y should be less then the Radius
And you'll have your answer.
I know this question is old but none of the answers consider the placement of the arc on the circle.
This algorithm considers that all angles are between 0 and 360, and the arcs are drawn in positive mathematical direction (counter-clockwise)
First you can transform to polar coordinates: radius (R) and angle (A). Note: use Atan2 function if available. wiki
R = sqrt ((X - CenterX)^2 + (Y - CenterY)^2)
A = atan2 (Y - CenterY, X - CenterX)
Now if R < Radius the point is inside the circle.
To check if the angle is between StartingAngle (S) and EndingAngle (E) you need to consider two possibilities:
1) if S < E then if S < A < E the point lies inside the slice
2) if S > E then there are 2 possible scenarios
if A > S
then the point lies inside the slice
if A < E
then the point lies inside the slice
In all other cases the point lies outside the slice.
Convert X,Y to polar coordinates using this:
Angle = arctan(y/x);
Radius = sqrt(x * x + y * y);
Then Angle must be between StartingAngle and EndingAngle, and Radius between 0 and your Radius.
You have to convert atan2() to into 0-360 before making comparisons with starting and ending angles.
(A > 0 ? A : (2PI + A)) * 360 / (2PI)