Calculate largest rectangle in a rotated rectangle

后端 未结 8 2256
你的背包
你的背包 2020-11-28 03:20

I\'m trying to find the best way to calculate the biggest (in area) rectangle which can be contained inside a rotated rectangle.

Some pictures should help (I hope) i

相关标签:
8条回答
  • 2020-11-28 04:09

    enter image description here

    Here is the easiest way to do this... :)

    Step 1
    //Before Rotation
    
    int originalWidth = 640;
    int originalHeight = 480;
    
    Step 2
    //After Rotation
    int newWidth = 701;  //int newWidth = 654;  //int newWidth = 513;
    int newHeight = 564; //int newHeight = 757; //int newHeight = 664;
    
    Step 3
    //Difference in height and width
    int widthDiff ;
    int heightDiff;
    int ASPECT_RATIO = originalWidth/originalHeight; //Double check the Aspect Ratio
    
    if (newHeight > newWidth) {
    
        int ratioDiff = newHeight - newWidth;
        if (newWidth < Constant.camWidth) {
            widthDiff = (int) Math.floor(newWidth / ASPECT_RATIO);
            heightDiff = (int) Math.floor((originalHeight - (newHeight - originalHeight)) / ASPECT_RATIO);
        }
        else {
            widthDiff = (int) Math.floor((originalWidth - (newWidth - originalWidth) - ratioDiff) / ASPECT_RATIO);
            heightDiff = originalHeight - (newHeight - originalHeight);
        }
    
    } else {
        widthDiff = originalWidth - (originalWidth);
        heightDiff = originalHeight - (newHeight - originalHeight);
    }
    
    Step 4
    //Calculation
    int targetRectanleWidth = originalWidth - widthDiff;
    int targetRectanleHeight = originalHeight - heightDiff;
    
    Step 5
    int centerPointX = newWidth/2;
    int centerPointY = newHeight/2;
    
    Step 6
    int x1 = centerPointX - (targetRectanleWidth / 2); 
    int y1 = centerPointY - (targetRectanleHeight / 2);
    int x2 = centerPointX + (targetRectanleWidth / 2);
    int y2 = centerPointY + (targetRectanleHeight / 2);
    
    Step 7
    x1 = (x1 < 0 ? 0 : x1);
    y1 = (y1 < 0 ? 0 : y1);
    
    0 讨论(0)
  • 2020-11-28 04:10

    @Andri is not working correctly for image where width > height as I tested. So, I fixed and optimized his code by such way (with only two trigonometric functions):

    calculateLargestRect = function(angle, origWidth, origHeight) {
        var w0, h0;
        if (origWidth <= origHeight) {
            w0 = origWidth;
            h0 = origHeight;
        }
        else {
            w0 = origHeight;
            h0 = origWidth;
        }
        // Angle normalization in range [-PI..PI)
        var ang = angle - Math.floor((angle + Math.PI) / (2*Math.PI)) * 2*Math.PI; 
        ang = Math.abs(ang);      
        if (ang > Math.PI / 2)
            ang = Math.PI - ang;
        var sina = Math.sin(ang);
        var cosa = Math.cos(ang);
        var sinAcosA = sina * cosa;
        var w1 = w0 * cosa + h0 * sina;
        var h1 = w0 * sina + h0 * cosa;
        var c = h0 * sinAcosA / (2 * h0 * sinAcosA + w0);
        var x = w1 * c;
        var y = h1 * c;
        var w, h;
        if (origWidth <= origHeight) {
            w = w1 - 2 * x;
            h = h1 - 2 * y;
        }
        else {
            w = h1 - 2 * y;
            h = w1 - 2 * x;
        }
        return {
            w: w,
            h: h
        }
    }
    

    UPDATE

    Also I decided to post the following function for proportional rectange calculating:

    calculateLargestProportionalRect = function(angle, origWidth, origHeight) {
        var w0, h0;
        if (origWidth <= origHeight) {
            w0 = origWidth;
            h0 = origHeight;
        }
        else {
            w0 = origHeight;
            h0 = origWidth;
        }
        // Angle normalization in range [-PI..PI)
        var ang = angle - Math.floor((angle + Math.PI) / (2*Math.PI)) * 2*Math.PI; 
        ang = Math.abs(ang);      
        if (ang > Math.PI / 2)
            ang = Math.PI - ang;
        var c = w0 / (h0 * Math.sin(ang) + w0 * Math.cos(ang));
        var w, h;
        if (origWidth <= origHeight) {
            w = w0 * c;
            h = h0 * c;
        }
        else {
            w = h0 * c;
            h = w0 * c;
        }
        return {
            w: w,
            h: h
        }
    }
    
    0 讨论(0)
提交回复
热议问题