Credit to @geozelot for the concept
This expression is an implementation of geozelot's comment.
Breakdown of the expression
- find the mean azimuth of all sequential pairs of vertices of all contour lines that intersect with each of the original polygons (perhaps median is a more appropriate statistic)
- use that value to rotate the polygon
- create an axis-aligned bounding box of the rotated polygon
- rotate the bounding box back using the negative of the mean azimuth
To clarify, the rotation angle is calculated per polygon, it is not a global value.
Geometry by Expression tool settings
The expression can be used in the Geometry by Expression tool, using the polygon layer as the input layer, and Polygon as the
Output geometry type.
centroid(bounds($geometry)), -- get the center point of the bouding box of the original polygon to use as the anchor point for rotation
intersection( -- get the intersection of the contour with the original polygon
aggregate('contours', 'collect', @geometry) -- change 'contours' for the name of your contours layer
array_mean( -- get the mean azimuth of all the contour vertices that intersect with the original polygon
geometry_n(@nodes, @element - 1)
rotate( -- rotate the axis-aligned bounding box back to the mean azimuth of the intersecting contour
bounds( -- create the axis-aligned bounding box
rotate( -- rotate the polygon by the mean azimuth of the intersecting contour
@center -- rotate around the center of the bounding box of the original geometry
degrees(-@mean_azi), -- negative angle to rotate back to starting angle
The red dotted outline is the generated bounding box, the solid blue outline is the oriented bounding box for comparison. The white points are the vertices used to obtain the mean azimuth of the contour segments.