Я работаю над WebGL (с 2d файловым редактором).
Я решил включить поворот непосредственно в инструмент обрезки, подобный фотосъемке iOS 8. то есть размер и положение фотографии изменяются динамически при повороте фотографии, чтобы область обрезки всегда содержалась в самой фотографии.
Однако я борюсь с некоторыми из математики.
У меня есть два прямоугольника, фотография и область обрезки.
Оба определены как:
var rect = {
x : x,
y : y,
w : width,
h : height
}
Прямоугольник, который сам определяет фотографию, также имеет свойство rotation
в радианах, что, конечно, описывает угол фотографии (в радианах).
Следует отметить, что координаты x
и y
прямоугольника фотографии ( не прямоугольник обрезки) фактически определяют центр фотографии и не верхняя левая точка. Хотя это может показаться странным, это упрощает расчеты для нас в другом месте и не должно влиять на этот вопрос. В интересах полноты я упоминаю это.
Происхождение трансформирования фотографии всегда задается как центр для урожая.
Когда угол фотографии 0
, а область обрезки - того же размера, что и фотография, прямоугольники выравниваются так:
Когда я поворачиваю фотографию, масштаб масштабирования применяется к прямоугольнику фотографий, чтобы гарантировать, что область посева остается в пределах границ фотографий:
Это достигается путем вычисления ограничивающего прямоугольника области урожая и из этого, выработки требуемого масштабного коэффициента для применения к прямоугольнику photo
:
TC.UI.PhotoCropper.prototype._GetBoundingBox = function(w,h,rads){
var c = Math.abs(Math.cos(rads));
var s = Math.abs(Math.sin(rads));
return({ w: h * s + w * c, h: h * c + w * s });
}
var bbox = this._GetBoundingBox(crop.w, crop.h, photo.rotation);
var scale = Math.max(1, Math.max(bbox.w/photo.w, bbox.h/photo.h));
В настоящее время он работает точно так, как предполагалось, и ширина прямоугольника фотографии правильно масштабируется везде, где имеет место croparea (и результирующее начало вращения).
Кроме того, поскольку это инструмент для обрезки фотографий, можно, конечно, изменить положение области посева. Обратите внимание, что при изменении положения croparea мы перемещаем прямоугольник photo
. (croparea всегда остается в центре, поскольку мы считаем, что это гораздо более естественно с сенсорными устройствами и все же приемлемо при использовании с мышью... Это то же самое и в iOS, и в окнах 8).
Поэтому мы в настоящее время зажимаем координаты x
и y
прямоугольника photo
к краям области посева следующим образом:
var maxX = crop.x + (crop.w/2) - (photo.w/2);
var maxY = crop.y + (crop.h/2) - (photo.w/2);
var minX = crop.x - (crop.w/2) + (photo.w/2);
var minY = crop.y - (crop.h/2) + (photo.h/2);
photo.x = Math.min(minX, Math.max(maxX, photo.x));
photo.y = Math.min(minY, Math.max(maxY, photo.y));
И вот, где я испытываю проблемы.
Когда область урожая не центрируется внутри фотографии, мы оказываемся в области croparea, движущейся за пределами фотографии, например:
Помните, что начало вращения всегда точно совпадает с центром области crop
На фотографии выше вы можете увидеть, что требуемая ширина правильно рассчитана, и фото правильно масштабируется, чтобы охватить область crop.
Однако, поскольку наша функция зажима проверяет только края ареала, мы заканчиваем нашу область урожая вне границ фотографий.
Мы хотели бы изменить нашу функцию зажима так, чтобы она учитывала поворот прямоугольника photo
. Поэтому координаты x
и y
(на скриншоте выше) должны быть правильно зажаты, чтобы убедиться, что конечный результат выглядит следующим образом:
К сожалению, я понятия не имею, с чего начать с математики и действительно может использовать некоторую помощь.
В настоящее время мы используем одну и ту же функцию зажима, одновременно вращаясь и перемещая прямоугольник photo
, и хотели бы продолжать делать это, если это возможно.