Calculate largest rectangle in a rotated rectangle

后端 未结 8 2287
你的背包
你的背包 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: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
        }
    }
    

提交回复
热议问题