A: Rotating and mounting a rectangle

after hard work my brain gets out of control .. (it's 11:40 PM in Turkey)

I am performing a rotation task .:

variables:

_cx = horizontal center of rect
_cy = vertical center of rect
_cos = cos value of current angle
_sin = sin value of current angle

to rotating any point in this rect :

function getx(x, y)
{
      return _cx + _cos * (x - _cx) - _sin * (y - _cy);
}
function gety(x, y)
{
      return _cy + _sin * (x - _cx) + _cos * (y - _cy);
}

I am trying to resize the rectangle before starting the rotation process to the maximum size that is set to the original borders. How can i do this?

Thank you for your progress.

EDIT: Igor Krivokon's decision

The problem was solved by Igor Krivokon, and here is a modified version of this solution, which works for each angle value

var h1:Number, h2:Number, hh:Number, ww:Number,
    degt:Number, d2r:Number, r2d:Number, deg:Number,
    sint:Number, cost:Number;
//@angle = given angle in radians
//@r is source/target rectangle
//@d2r is static PI / 180 constant for degree -> radian conversation
//@r2d is static 180 / PI constant for radian -> degree conversation
d2r = 0.017453292519943295769236907683141;
r2d = 57.295779513082320876798154814105;
deg = Math.abs(angle * r2d) % 360;
if(deg < 91)
{
    degt = angle;
}else if(deg < 181){
    degt = (180 - deg) * d2r;
}else if(deg < 271){
    degt = (deg - 180) * d2r;
}else{
    degt = (360 - deg) * d2r;
}

sint = Math.sin(degt);
cost = Math.cos(degt);

h1 = r.height * r.height / (r.width * sint + r.height * cost);
h2 = r.height * r.width / (r.width * cost + r.height * sint);
hh = Math.min(h1, h2);
ww = hh * r.width / r.height;
r.x = (r.width - ww) * .5;
r.y = (r.height - hh) * .5;
r.height = hh;
r.width = ww;

thanks

+3
source share
4 answers

If your original sizes, where h and w, and you turned, at the angle phi, try to calculate a new height

h1 = h*h / (w*sin(phi) + h*cos(phi))

and

h2 = h*w / (w*cos(phi) + h*sin(phi))

hw h1 h2.

, , w' = h' * w / h.

, - :)

+5

4 . ( , ), 8 . 4 . .

( , 45, -45, 135, -135 , mx + b), ( , ), (y = 0, y = w, x = 0, x = h, , ) , ( , ). , , .

?

0
function resize_factor()
{
    /* Find how far the upper-left corner sticks up beyond the top */
    overtop = gety(0, 0);
    /* Compute a vertical resize factor that would put that point at the top */
    /* (be sure to use floating point arithmetic) */
    vertical_resize = _cy / (_cy - overtop);

    /* Do the same for the lower-left corner sticking out beyond the left */
    /* (using 2*_cy for the height of the rectangle) */
    overleft = getx(0, 2*_cy);    
    horizontal_resize = _cx / (_cx - overleft);

    /* Return whichever resize constraint is stricter */
    return min(vertical_resize, horizontal_resize);
}

function resize_x(x)
{
    /* To get location of a point, after resize, before rotation... */
    /* ...multiply its resize factor by its distance from the center. */
    return resize_factor()*(x - _cx) + _cx;
}

function resize_y(y)
{
    return resize_factor()*(y - _cy) + _cy;
}

/* These resized coordinates can be used inside any other code you want: */
function getx_after_resize_and_rotate(x, y)
{
    return getx( resized_x(x), resized_y(y) );
}

Notes. This code assumes that the angle rotates clockwise by less than 90 degrees (due to what your pictures show). If your angle is something else, you may need to check all 4 corners and determine which ones are the more successful overlay and influx.

0
source
    fitRect: function( rw,rh,radians ){
            var x1 = -rw/2,
                x2 = rw/2,
                x3 = rw/2,
                x4 = -rw/2,
                y1 = rh/2,
                y2 = rh/2,
                y3 = -rh/2,
                y4 = -rh/2;

            var x11 = x1 * Math.cos(radians) + y1 * Math.sin(radians),
                y11 = -x1 * Math.sin(radians) + y1 * Math.cos(radians),
                x21 = x2 * Math.cos(radians) + y2 * Math.sin(radians),
                y21 = -x2 * Math.sin(radians) + y2 * Math.cos(radians), 
                x31 = x3 * Math.cos(radians) + y3 * Math.sin(radians),
                y31 = -x3 * Math.sin(radians) + y3 * Math.cos(radians),
                x41 = x4 * Math.cos(radians) + y4 * Math.sin(radians),
                y41 = -x4 * Math.sin(radians) + y4 * Math.cos(radians);

            var x_min = Math.min(x11,x21,x31,x41),
                x_max = Math.max(x11,x21,x31,x41);

            var y_min = Math.min(y11,y21,y31,y41);
                y_max = Math.max(y11,y21,y31,y41);

            return [x_max-x_min,y_max-y_min];
        }
0
source

Source: https://habr.com/ru/post/1709629/


All Articles