How to place svg shapes in a circle? - d3.js

I'm playing a bit with D3.js and I got most things working. But I want to place my svg shapes in a circle. So I will show the difference in data with color and text. I know how to draw circles and pie charts, but I want to basically have a circle of same size circles. And not have them overlap, the order is irrelevant. I don't know where to start, to find out the x & y for each circle.

If I understand you correctly, this is a fairly standard math question:
Simply loop over some angle variable in the appropriate step size and use sin() and cos() to calculate your x and y values.
For example:
Let's say you are trying to place 3 objects. There are 360 degrees in a circle. So each object is 120 degrees away from the next. If your objects are 20x20 pixels in size, place them at the following locations:
x1 = sin( 0 * pi()/180) * r + xc - 10; y1 = cos( 0 * pi()/180) * r + yc - 10
x2 = sin(120 * pi()/180) * r + xc - 10; y2 = cos(120 * pi()/180) * r + yc - 10
x3 = sin(240 * pi()/180) * r + xc - 10; y3 = cos(240 * pi()/180) * r + yc - 10
Here, r is the radius of the circle and (xc, yc) are the coordinates of the circle's center point. The -10's make sure that the objects have their center (rather than their top left corner) on the circle. The * pi()/180 converts the degrees to radians, which is the unit most implementations of sin() and cos() require.
Note: This places the shapes equally distributed around the circle. To make sure they don't overlap, you have to pick your r big enough. If the objects have simple and identical boundaries, just lay out 10 of them and figure out the radius you need and then, if you need to place 20, make the radius twice as big, for 30 three times as big and so forth. If the objects are irregularly shaped and you want to place them in the optimal order around the circle to find the smallest circle possible, this problem will get extremely messy. Maybe there's a library for this, but I don't have one in the top of my head and since I haven't used D3.js, I'm not sure whether it will provide you with this functionality either.

Here's another approach to this, for shapes of arbitrary size, using D3's tree layout: http://jsfiddle.net/nrabinowitz/5CfGG/
The tree layout (docs, example) will figure out the x,y placement of each item for you, based on a given radius and a function returning the separation between the centers of any two items. In this example, I used circles of varying sizes, so the separation between them is a function of their radii:
var tree = d3.layout.tree()
.size([360, radius])
.separation(function(a, b) {
return radiusScale(a.size) + radiusScale(b.size);
});
Using the D3 tree layout solves the first problem, laying out the items in a circle. The second problem, as #Markus notes, is how to calculate the right radius for the circle. I've taken a slightly rough approach here, for the sake of expediency: I estimate the circumference of the circle as the sum of the diameters of the various items, with a given padding in between, then calculate radius from the circumference:
var roughCircumference = d3.sum(data.map(radiusScale)) * 2 +
padding * (data.length - 1),
radius = roughCircumference / (Math.PI * 2);
The circumference here isn't exact, and this will be less and less accurate the fewer items you have in the circle, but it's close enough for this purpose.

Related

Cover large rectangles with identical small rectangles

The problem states that I have a big rectangle, with dimension L and W, and unlimited number of identical small rectangles, with dimension l and w. L * W is guaranteed to be larger than l *w. So I want to find out the maximum number of small rectangles that I can put into the big rectangle, without overlapping. You can put the small rectangles in any orientation you like.
Axis Aligned
Rectangles fit best when they are tiled, with no space between. So, an outline of how to do it:
First, figure out how many fit if you just tile them in:
lFit = L / l // integer division for these, no remainder
wFit = W / w
You know that you can fit lFit * wFit rectangles inside if you stack them in the same orientation as the big rectangle. Check again with the other orientation, and choose the bigger one as your base.
Now you may have some space left over. That space is made up of rectangles. You can easily find the size of these from the previous step. Run it again for these smaller rectangles and add to the base number. Recurse until no more fit.
If no tiles will fit into the "remaining" smaller rectangle, it's time to check for tilted ones.
Diagonal
Once your tile does not fit axis-aligned into the rectangle, you need to tilt it. You can pack the most tiles in by tilting them just enough to fit in the longest box dimension, and placing it firmly against three walls. Then you try stacking more in below it.
Note: for all the math here, I'm using width as the "longest edge". If your rectangle/tile doesn't match, just flip the dimensions.
To figure out what the proper rotation angle is, you can use a trial/error binary search. I'm sure there's a more "mathy" way to do it, but this works well enough. The formula for the bounding width of a rotated rectangle is(angle in radians):
width = w * cos(angle) + h * sin(angle)
To do a trial/error, just loop it until you reach your tolerance:
// boxWidth, tileWidth, tileHeight
public static double getAngle(double bw, double tw, double th){
double err = 10;
double maxAngle = PI * 0.25; // 45 degrees, any more would be taller than wide
double angle = maxAngle * 0.5; // start in the middle
double angleDelta = angle * 0.5; // amount to change;
count = 0;
while(count++ < 100){
double rotatedWidth = tw * Math.cos(angle) + th * Math.sin(angle);
err = rotatedWidth - bw;
if(Math.abs(err) < TOLERANCE){
return angle;
} else if(err < 0){
angle -= angleDelta;
} else {
angle += angleDelta;
}
angleDelta *= 0.5;
}
return -1; // found no good angle in 100 attempts
}
Once you have the angle, you can use basic trig to figure out some other points:
Find the lowest y-point of the top edge of the tile where it will be placed. Call this y1
y1 = sin(angle) * tileWidth
Find the lowest point of the left edge of the tile. Call this y2
y2 = sin((PI * 0.5) - radians) * tileHeight
Each added tile will take up y2 vertical space, so the number that will fit is:
(boxHeight - y1) / y2
I created a small ideone.com example that you can play with, also. The code is rather ugly, but it works. For your example in comments(13x8, 14x1), it shows:
Rotated 26.23397827148437 degrees
y1 = 6.188525444904378
y2 = 0.8969959689614577
numTiles = 2

Issues finding outward facing angle between point on circle and center

I'm finding the angle between the centre of my circle and the triangle in degrees like so:
atan2((centre.y-triangle.y), (centre.x-triangle.x) * 180 / PI - 90
I'm setting the rotation of my triangle object which takes degrees as a parameter. The issue is all of my triangles are not rotated outwards correctly, which I presume is a result of the calculation of my position which is done like this:
triangle.x = -(width / 2) + (stage.width / 2) + radius * sin((index / total) * (2 * PI))
Here is an example of what happens, as you can see the last few triangles in the circle appear to be facing outwards correctly.
OK, I need some answer space to put all this info.
First of all you need to calculate the angle of a given triangle. You can do that with the following:
int angle = (360 / numberOfElements) * triangleIndex;
You also need to work out a "slice" (don't no what that is, just read it) to use for calculating the new positon:
var slice = (2 * Math.PI / numberOfElements) * triangleIndex;
Next, you need to work out the position of each triangle:
int tempRadius = radius + (int)(triangleHeight / 2);
int traingleCentreX = (int)(centre.X + tempRadius * Math.Cos(slice));
int traingleCentreY = (int)(centre.Y + tempRadius * Math.Sin(slice));
//assuming centre is the centre of the circle
[Credit for all this maths goes to this answer
]
Now that you have the correct position of each of your triangles, you should be able to apply the rotation (using angle) and it should look amaze-balls!
NOTE: Positions will be calculating starting at the right (i.e. 90 degrees). So when doing the rotation add an extra 90 degrees!
http://jsfiddle.net/TcENr/ (it as the quickest to test!)
The issue with the subtle offset of the rotation was because I wasn't adding the half width and height of the triangle to it's position, this fixed the problem:
rotation = atan2(centreY-(triangleY+triangleHalfHeight),centreX-(triangleX+triangleHalfWidth)) * 180 / Math.PI - 90;

Bounding circle of set of circles

I'm trying to implement the following in Java.
Given a list of circles of different sizes (possibly) and positions, determine a large circle (position and size) which just exactly encloses all the circles.
public class Circle {
public int x, y, radius;
}
Any ideas?
The miniball-of-balls problem has been studied in "The smallest enclosing ball of balls: combinatorial structure and algorithms", for example. One outcome of this research was that at least some algorithms for the miniball-of-points problem (like Welzl's algorithm) cannot easily be generalised from points to balls.
The above paper presents an O(n)-algorithm to compute the miniball of a set of balls (n being the number of input balls, i.e., circles in 2D). A C++ implementation thereof is available in the Computational Geometry Algorithms Library (CGAL). (You do not need to use all of CGAL; simply extract the required header and source files.)
Note: I am a co-author of the above paper and the author of the CGAL Min_sphere_of_spheres package.
I have a roughly O(n4) true solution that I'm implementing for a product in JavaScript:
You need a function to determine whether a solution is valid: to be precise, a function that will check if all the circles lie within the proposed super-circle. This is fairly trivial: for every circle Ci, require that the distance from the centre of the super circle to the centre of Ci plus the radius of Ci is less than or equal to the radius of the super-circle.
Then, construct a super-circle out of every pair and every triple of circles.
For a pair, draw a line from the centre of Ci to the centre of Cj. Extend the line out on each end by the radius of the respective circle. The midpoint of the line is the centre of the super-circle, and its radius is half the length of the line.
For 3 circles, this is the Problem of Apollonius: http://mathworld.wolfram.com/ApolloniusProblem.html; noting that you need to get the correct signs to get one that will include all three circles.
The correct solution is the valid super-circle with the smallest radius.
Here's my code:
'use strict';
/**
* Epsilon value for floating point equality.
* #const
*/
var EPSILON = 1E-6;
/**
* Calculates the minimum bounding circle for a set of circles.
* O(n^4)
*
* #param {Array.<Object.<string, number>>} circles A list of 2+ circles.
* #return {Object.<string, number>} {cx, cy, radius} of the circle.
*/
function minimumBoundingCircleForCircles(circles) {
var areAllCirclesInOrOnCircle = function(circle) {
for (var i = 0; i < circles.length; i++) {
if (!isCircleInOrOnCircle(circles[i], circle)) return false;
}
return true;
};
// try every pair and triple
var best = {radius: 9E9};
for (var i = 0; i < circles.length; i++) {
for (var j = i + 1; j < circles.length; j++) {
var circle = circleFrom2Circles(circles[i], circles[j]);
if (areAllCirclesInOrOnCircle(circle) &&
circle.radius < best.radius) {
best.cx = circle.cx; best.cy = circle.cy;
best.radius = circle.radius;
}
for (var k = j + 1; k < circles.length; k++) {
var signs = [-1, 1, 1, 1];
circle = apollonius(circles[i], circles[j], circles[k],
signs);
if (areAllCirclesInOrOnCircle(circle) &&
circle.radius < best.radius) {
best.cx = circle.cx; best.cy = circle.cy;
best.radius = circle.radius;
}
}
}
}
return best;
}
/**
* Calculates a circle from 2 circles.
*
* #param {Object.<string, number>} circle1 The first circle.
* #param {Object.<string, number>} circle2 The second circle.
* #return {Object.<string, number>} cx, cy, radius of the circle.
*/
function circleFrom2Circles(circle1, circle2) {
var angle = Math.atan2(circle1.cy - circle2.cy,
circle1.cx - circle2.cx);
var lineBetweenExtrema = [[circle1.cx + circle1.radius * Math.cos(angle),
circle1.cy + circle1.radius * Math.sin(angle)],
[circle2.cx - circle2.radius * Math.cos(angle),
circle2.cy - circle2.radius * Math.sin(angle)]];
var center = lineMidpoint(lineBetweenExtrema[0], lineBetweenExtrema[1]);
return { cx: center[0],
cy: center[1],
radius: lineLength(lineBetweenExtrema[0],
lineBetweenExtrema[1]) / 2
};
}
/**
* Solve the Problem of Apollonius: a circle tangent to all 3 circles.
* http://mathworld.wolfram.com/ApolloniusProblem.html
*
* #param {Object.<string, number>} circle1 The first circle.
* #param {Object.<string, number>} circle2 The second circle.
* #param {Object.<string, number>} circle3 The third circle.
* #param {Array.<number>} signs The array of signs to use.
* [-1, 1, 1, 1] gives max circle.
* #return {Object.<string, number>} The tangent circle.
*/
function apollonius(circle1, circle2, circle3, signs) {
var sqr = function(x) { return x * x };
var a1 = 2 * (circle1.cx - circle2.cx);
var a2 = 2 * (circle1.cx - circle3.cx);
var b1 = 2 * (circle1.cy - circle2.cy);
var b2 = 2 * (circle1.cy - circle3.cy);
var c1 = 2 * (signs[0] * circle1.radius + signs[1] * circle2.radius);
var c2 = 2 * (signs[0] * circle1.radius + signs[2] * circle3.radius);
var d1 = (sqr(circle1.cx) + sqr(circle1.cy) - sqr(circle1.radius)) -
(sqr(circle2.cx) + sqr(circle2.cy) - sqr(circle2.radius));
var d2 = (sqr(circle1.cx) + sqr(circle1.cy) - sqr(circle1.radius)) -
(sqr(circle3.cx) + sqr(circle3.cy) - sqr(circle3.radius));
// x = (p+q*r)/s; y = (t+u*r)/s
var p = b2 * d1 - b1 * d2;
var q = (- b2 * c1) + (b1 * c2);
var s = a1 * b2 - b1 * a2;
var t = - a2 * d1 + a1 * d2;
var u = a2 * c1 - a1 * c2;
// you are not expected to understand this.
// It was generated using Mathematica's Solve function.
var det = (2 * (-sqr(q) + sqr(s) - sqr(u)));
var r = (1 / det) *
(2 * p * q + 2 * circle1.radius * sqr(s) + 2 * t * u -
2 * q * s * circle1.cx - 2 * s * u * circle1.cy + signs[3] *
Math.sqrt(sqr(-2 * p * q - 2 * circle1.radius * sqr(s) - 2 * t * u +
2 * q * s * circle1.cx + 2 * s * u * circle1.cy) -
4 * (-sqr(q) + sqr(s) - sqr(u)) *
(-sqr(p) + sqr(circle1.radius) * sqr(s) - sqr(t) +
2 * p * s * circle1.cx - sqr(s) * sqr(circle1.cx) +
2 * s * t * circle1.cy - sqr(s) * sqr(circle1.cy))))
//console.log(r);
r = Math.abs(r);
var x = (p + q * r) / s;
var y = (t + u * r) / s;
//console.log(x); console.log(y);
return {cx: x, cy: y, radius: r};
}
/**
* Is the circle inside/on another circle?
*
* #param {Object.<string, number>} innerCircle the inner circle.
* #param {Object.<string, number>} outerCircle the outer circle.
* #return {boolean} is the circle inside/on the circle?
*/
function isCircleInOrOnCircle(innerCircle, outerCircle) {
return ((lineLength([innerCircle.cx, innerCircle.cy],
[outerCircle.cx, outerCircle.cy]) +
innerCircle.radius - EPSILON) < outerCircle.radius);
}
/**
* Calculates the length of a line.
* #param {Array.<number>} pt1 The first pt, [x, y].
* #param {Array.<number>} pt2 The second pt, [x, y].
* #return {number} The length of the line.
*/
function lineLength(pt1, pt2) {
return Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) +
Math.pow(pt1[1] - pt2[1], 2));
}
/**
* Calculates the midpoint of a line.
* #param {Array.<number>} pt1 The first pt, [x, y].
* #param {Array.<number>} pt2 The second pt, [x, y].
* #return {Array.<number>} The midpoint of the line, [x, y].
*/
function lineMidpoint(pt1, pt2) {
return [(pt1[0] + pt2[0]) / 2,
(pt1[1] + pt2[1]) / 2];
}
The Wikipedia article Smallest circle problem describes a linear average time algorithm for the case where the sizes of the initial circles are equal. It looks straightforward to generalize it to differently-sized initial circles, though I'm not sure what happens to the complexity analysis then.
You could find the max boundaries (xmin, xmax, ymin, ymax), then take max on both axis, then ask java to draw an ellipse in that square or take the center of it and the side as diameter.
No ?
Regards,
Stéphane
Oops, the following does not work, as noted in comments:
Start by solving the problem for 3 circles. In that case the circumscribed circle will touch each of the three inner circles, and you can find its center as the intersection of two hyperbolas. (The locus of points that have a given difference in distance to two fixed points is a hyperbola). After a bit of algebra, that boils down to a quadratic equation.
Now add more inner circles by induction. At the beginning of each step you know the smallest circle that encompasses all of the old circles; it will touch three particular old "corner" circles. If the new circle is inside that one, there's nothing to do. If not, combine the new circle with all three ways to chose two of the old corner circles and compute the circumscribed circle for each of those triples. One of them should include the fourth one, which is now not a corner circle anymore.
Proceed until you have added all circles.
This gives a linear-time algorithm with bounded rounding errors (because each circumscribed circle is computed afresh from pristine input coordinates).
My suggested algorithm is similar to that of Svante but with a few differences.
The idea is to first create a circle which trivially encompasses all subcircles and then shrink it like a bubble until it is pinned by 1,2, or 3 circles.
first approximation:
a circle with centre 0,0 and radius max(distance from 0,0 of subcircle + radius of subcircle)
if the subcircle which determines the radius of the circle encloses all other subcircles, then it is trivially the correct result, and can be returned
second approximation:
reduce the radius of the circle found in the first approximation while keeping it tangent to the subcircle which it is 'pinned' to, moving the centre towards the pinned subcircle, until it becomes tangent to another subcircle.
final result:
reduce the radius of the circle again, keeping it tangent to the two subcircles found above, until either another subcircle becomes tangent to the circle, or the centre of the circle lies on the line between the centres of the two subcircles it is pinned to. This should be the minimum because there is no way from here to reduce the radius of the circle without one of the subcircles 'breaking through'
The part of the algorithm I'm not sure about is the 'reduce the radius until another subcircle becomes tangent' part. Obviously a binary search can give a good enough approximation in a decent amount of time, but I suspect you can reduce it to an equation.
I think that this can be done in three steps:
First bounding circle c1:
The centre is determined by xc1 = (xmax + xmin) / 2
and yc1 = (ymax + ymin) / 2.
For each circle, calculate the distance of its centre to the centre of c1 plus its radius (I call this the over-distance).
The maximum of these values is the radius of c1. The corresponding circle is a.
Second bounding circle c2:
(In this step, you move the centre of c1 in direction of a as far as possible.)
For each circle except a, determine how much you have to move the centre of c1 in the direction of a so that the over-distance from there to this circle is the same as to a. The minimum of this determines the centre of c2. The corresponding circle is b. The over-distance to a and b (both are the same) is the radius of c2.
Third bounding circle c3:
(In this step, you move the centre of c2 in the direction between a and b as far as possible.)
Determine the direction v in which you can move c2 such that the over-distance to a and b stays the same.
For each circle except a and b, determine how much you have to move the centre of c2 in direction v so that the over-distance from there to this circle is the same as to a and b. The minimum of this determines the centre of c3. The radius is the over-distance to the three circles found.
I believe that c3 is the solution (edit) a good first approximation. You can get better solutions by iteratively dropping the first circle and repeating the third step. If you arrive at a set of three circles that you have already seen, this should might be the final solution.
I'd try to find the topmost western point, then the southern downmost point, then make a circle with those points as diameter.
In order to find those points, I'd cycle through the center of the circles and their radius.
So it ends up in:
initiate max object and min object to average center of circle and zero radius
For every circle object
calculate topmost western point of the circle
check if further away than current point
if further, calculate position of topmost western point required to pass over this new point and set as new min object
calculate down most eastern point of the circle
do the same as previous step, only for max object
make a circle with center equals to middle of min-max line and radius equals to half min-max line length
If you are the bookworm type, good university libraries stock this: E.Welzl, Smallest Enclosing Disks (Balls and Ellipsoids), in H. Maurer (Ed.), New Results and New Trends in Computer Science, Lecture Notes in Computer Science, Vol. 555, Springer-Verlag, 359–37 (1991)
And if you want to read C++ code and adapt it to Java, http://miniball.sourceforge.net/.
With circles, d=2, of course.
With two circles it is easy. A line through both centres will hit the perimeter where an enclosing circle would contact them.
With more circles you would need to apply FEM (finite element analysis- http://en.wikipedia.org/wiki/Finite_element_method) on each perimeter point with the potential to be a point of contact with the outside circle. This rules out those segments which are facing other circles, for example. The computation is still rather large as you proceed to apply different radius's to your points until you find the smallest ones that intersects all the others at a common point- the centre of your enclosing cirlce.
I don't think its a packing problem per se. It sounds more like convex-hull. I think the question is:
You are given a set of circles on the plane. Find the center point and radius of the smallest circle for which every boundary point of each circle lies within or on the boundary of the containing circle.
For that, you can just run recursively: find the smallest circle containing the first two circles (and that circle's center lies on the line connecting the two centers, and its radius should be simple to determine as well), replace the first two circles with the new circle, and repeat.
The correctness of this algorithm belongs in mathematics.
It is very difficult problem, I would just outline possible ways to it, you have to finish it yourself. I assume you want to find minimal bounding circle.
Formalizing your problem - having xi, yi, ri for i = 1..N, you are looking for point [x, y] such that:
max(distance([x, y], [xi, yi]) + ri)
is minimal. This is a non-trivial minimax problem. First look at the simpler version of this problem Smallest circle problem, which is just for points:
max(distance([x, y], [xi, yi]))
So first try to improve the algorithms proposed in the above link to solve the more complex case. If this way is impassable, you might probably need to go for quadratic programming. Good luck...

Scaling vectors from a center point?

I'm trying to figure out if I have points that make for example a square:
* *
* *
and let's say I know the center of this square.
I want a formula that will make it for eample twice its size but from the center
* *
* *
* *
* *
Therefore the new shape is twice as large and from the center of the polygon. It has to work for any shape not just squares.
I'm looking more for the theory behind it more than the implementation.
If you know the center point cp and a point v in the polygon you would like to scale by scale, then:
v2 = v - cp; // get a vector to v relative to the centerpoint
v2_scaled = v2 * scale; // scale the cp-relative-vector
v1_scaled = v2_scaled + cp; // translate the scaled vector back
This translate-scale-translate pattern can be performed on vectors of any dimension.
If you want the shape twice as large, scale the distance of the coordinates to be sqrt(2) times further from the center.
In other words, let's say your point is at (x, y) and the center is (xcent, ycent). Your new point should be at
(xcent + sqrt(2)*(x - xcent), ycent + sqrt(2)*(y - ycent))
This will scale the distances from the new 'origin', (xcent, ycent) in such a way that the area doubles. (Because sqrt(2)*sqrt(2) == 2).
I'm not sure there's a clean way to do this for all types of objects. For relatively simple ones, you should be able to find the "center" as the average of all the X and Y values of the individual points. To double the size, you find the length and angle of a vector from the center to the point. Double the length of the vector, and retain the same angle to get the new point.
Edit: of course, "twice the size" is open to several interpretations (e.g., doubling the perimeter vs. doubling the area) These would change the multiplier used above, but the basic algorithm would remain essentially the same.
To do what you want you need to perform three operations: translate the square so that its centroid coincides with the origin of the coordinate system, scale the resulting square, translate it back.

Calculating the Bounding Rectangle at an Angle of a Polygon

I have the need to determine the bounding rectangle for a polygon at an arbitrary angle. This picture illustrates what I need to do:
alt text http://kevlar.net/RotatedBoundingRectangle.png
The pink rectangle is what I need to determine at various angles for simple 2d polygons.
Any solutions are much appreciated!
Edit:
Thanks for the answers, I got it working once I got the center points correct. You guys are awesome!
To get a bounding box with a certain angle, rotate the polygon the other way round by that angle. Then you can use the min/max x/y coordinates to get a simple bounding box and rotate that by the angle to get your final result.
From your comment it seems you have problems with getting the center point of the polygon. The center of a polygon should be the average of the coordinate sums of each point. So for points P1,...,PN, calculate:
xsum = p1.x + ... + pn.x;
ysum = p1.y + ... + pn.y;
xcenter = xsum / n;
ycenter = ysum / n;
To make this complete, I also add some formulas for the rotation involved. To rotate a point (x,y) around a center point (cx, cy), do the following:
// Translate center to (0,0)
xt = x - cx;
yt = y - cy;
// Rotate by angle alpha (make sure to convert alpha to radians if needed)
xr = xt * cos(alpha) - yt * sin(alpha);
yr = xt * sin(alpha) + yt * cos(alpha);
// Translate back to (cx, cy)
result.x = xr + cx;
result.y = yr + cx;
To get the smallest rectangle you should get the right angle. This can acomplished by an algorithm used in collision detection: oriented bounding boxes.
The basic steps:
Get all vertices cordinates
Build a covariance matrix
Find the eigenvalues
Project all the vertices in the eigenvalue space
Find max and min in every eigenvalue space.
For more information just google OBB "colision detection"
Ps: If you just project all vertices and find maximum and minimum you're making AABB (axis aligned bounding box). Its easier and requires less computational effort, but doesn't guarantee the minimum box.
I'm interpreting your question to mean "For a given 2D polygon, how do you calculate the position of a bounding rectangle for which the angle of orientation is predetermined?"
And I would do it by rotating the polygon against the angle of orientation, then use a simple search for its maximum and minimum points in the two cardinal directions using whatever search algorithm is appropriate for the structure the points of the polygon are stored in. (Simply put, you need to find the highest and lowest X values, and highest and lowest Y values.)
Then the minima and maxima define your rectangle.
You can do the same thing without rotating the polygon first, but your search for minimum and maximum points has to be more sophisticated.
To get a rectangle with minimal area enclosing a polygon, you can use a rotating calipers algorithm.
The key insight is that (unlike in your sample image, so I assume you don't actually require minimal area?), any such minimal rectangle is collinear with at least one edge of (the convex hull of) the polygon.
Here is a python implementation for the answer by #schnaader.
Given a pointset with coordinates x and y and the degree of the rectangle to bound those points, the function returns a point set with the four corners (and a repetition of the first corner).
def BoundingRectangleAnglePoints(x,y, alphadeg):
#convert to radians and reverse direction
alpha = np.radians(alphadeg)
#calculate center
cx = np.mean(x)
cy = np.mean(y)
#Translate center to (0,0)
xt = x - cx
yt = y - cy
#Rotate by angle alpha (make sure to convert alpha to radians if needed)
xr = xt * np.cos(alpha) - yt * np.sin(alpha)
yr = xt * np.sin(alpha) + yt * np.cos(alpha)
#Find the min and max in rotated space
minx_r = np.min(xr)
miny_r = np.min(yr)
maxx_r = np.max(xr)
maxy_r = np.max(yr)
#Set up the minimum and maximum points of the bounding rectangle
xbound_r = np.asarray([minx_r, minx_r, maxx_r, maxx_r,minx_r])
ybound_r = np.asarray([miny_r, maxy_r, maxy_r, miny_r,miny_r])
#Rotate and Translate back to (cx, cy)
xbound = (xbound_r * np.cos(-alpha) - ybound_r * np.sin(-alpha))+cx
ybound = (xbound_r * np.sin(-alpha) + ybound_r * np.cos(-alpha))+cy
return xbound, ybound

Resources