О: прямоугольное вращение и примерка - PullRequest
3 голосов
/ 03 июня 2009

после тяжелой работы мой мозг выходит из строя .. (в 11:40 вечера в Турции)

Я выполняю ротационную работу.

переменные:

_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);
}

Я пытаюсь изменить размер данного прямоугольника до поворота до максимального размера, который помещается в исходных границах ... как я могу это сделать?

спасибо за ваше продвижение

РЕДАКТИРОВАТЬ: решение Игоря Кривокона

Проблема решена Игорем Кривоконом, и вот модифицированная версия этого решения, которая работает для каждого значения угла

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;

Спасибо

Ответы [ 4 ]

5 голосов
/ 03 июня 2009

Если ваши исходные размеры, где h и w, а вы повернули, на угол phi, попробуйте рассчитать новую высоту

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

и

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

И выберите высоту буквы h 'как наименьшее из h1 и h2.

Тогда, очевидно, новая ширина w' = h' * w / h.

Пожалуйста, попробуйте - у меня не было времени проверить свою математику:)

0 голосов
/ 06 октября 2010
    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 голосов
/ 03 июня 2009
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) );
}

Примечания. В этом коде предполагается, что угол поворота по часовой стрелке составляет менее 90 градусов (потому что это то, что показывают ваши фотографии). Если у вас какой-то другой угол, вам, возможно, придется проверить все 4 угла и определить, какие из них являются самыми дальними над и над левым.

0 голосов
/ 03 июня 2009

разделите прямоугольник на 4 меньших прямоугольника. Разрежьте его пополам по диагонали (до поворота, от угла к центральной точке), и у вас будет 8 треугольников. Вам нужно только 4 из них. После вашего вращения гипотенуза этих треугольников торчит из оригинальной рамки границ.

определить формулу для гипотенузы (у вас есть исходный угол 45, -45, 135, -135 и начальная точка, то есть mx + b), преобразовать эти линии (изменить их наклоны, добавив вращение) пересекают эти линии с граничными стенками (y = 0, y = w, x = 0, x = h, формула расстояния, тест для бесконечных случаев) и выясняем, какая гипотенуза самая короткая (от центра к стене, в углу) Поскольку все гипотенузы были одинаковой длины, просто измените их размер до нового значения, у вас есть новый прямоугольник.

Я правильно делаю?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...