PDA

Просмотр полной версии : Найти высоту и ширину деформированого прямоугольника


wvxvw
15.01.2008, 21:55
Вот, чет уже второй день никак не срастается, а казалось так просто... %)
Вобщем, задачка такая:
На входе получаем деформированый как угодно клип (для простоты - прямоугольник). Нужно узнать длины сторон до деформации, желательно не изменяя _rotation.
Для простоты можно оформить как в задачнике:
Дано клип размерами 459,7х459,7, сжат по высоте на 50% и повернут на 45 градусов.
(Изначально он соответственно был 400х500, но вот как из имеющихся данных это получить - я не знаю =)

18685
кртинку приложил, если не понятно описал.

iNils
15.01.2008, 22:41
Высота и ширина это проекция фигуры на оси. Поэтому реальные размеры, без обратных преобразований, можно определить только зная математическое описание фигуры.

wvxvw
15.01.2008, 23:09
А какие еще параметры нужно знать? руководствуясь только приведенными данными флеш всегда изобразит одну и ту же фигуру - а я нет %)))

Т.е. в итоге, то, что я сделал - просто до пересчета поворачиваю прямоугольник в 0 градусов, тогда высота и ширина помноженные на скейл и будут равны соответствующим сторонам. Но это как-то криво...

iNils
15.01.2008, 23:21
руководствуясь только приведенными даннымиС чего это? Флеш также знает координаты вершин формы. А ты нет :)

wvxvw
16.01.2008, 00:08
Мож он и знает, но не признается, партизан, млин =) Как бы их у него спросить? %)
А вообще, похоже, что не, не знает, ему и этого хватает как-то...

ЗЫ. И вообще, если сделав пару нехитрых операций с клипом я тоже смогу получить нужные данные - значит их можно и вычислить как-то, вот ток чего-то у меня никак не выходит...

olexandr
16.01.2008, 03:33
озадачил ты конечно :)
посидел полчасика - вроде придумал (если конечно мы знаем _rotation)
сейчас спать хочется, если до утра ответа не будет, то на работе набросаю! :)

а, вообще, +10 за задачу! :)

iNils
16.01.2008, 09:18
И вообще, если сделав пару нехитрых операций с клипом я тоже смогу получить нужные данные - значит их можно и вычислить как-то, вот ток чего-то у меня никак не выходит...
Флеш хранит первоначальные данные объекта и применяет к ним матричные преобразования, а не к текущим данным.

CorC
16.01.2008, 10:09
Из таких входных данных решить эту задачу математически нельзя, под эти условия подходит любой прямоугольник, вписанный в этот квадрат. Поворачивать придется.

iNils
16.01.2008, 10:20
Задача часто не имеет определенного ответа.
Пример. Берем прямоугольник с теми же размерами, 400 на 500. Поворачиваем его на 45 градусов и получаем размеры 636.4 на 636.4, а квадрат со сторонами 450 на 450, при том же угле, дает те же самые 636.4 на 636.4.
То есть, при одинаком угле поворота и конечных размерах, мы имеем разные базовые размеры.

olexandr
16.01.2008, 11:05
Да, iNils, в посте №9 прав! А я вчера недосмотрел, когда писал свое утверждение. Я тоже думал об этом и пробовал поворачивать прямоугольник, но не учел при этом, что периметр должен оставаться константой.
А для того, чтобы решить задачу, я так понимаю нужна еще хотя бы пропорция между сторонами.

Ostgur
16.01.2008, 11:50
в вершины мувиклипы всунуть, да и всё.

wvxvw
16.01.2008, 12:16
Задача часто не имеет определенного ответа.
Пример. Берем прямоугольник с теми же размерами, 400 на 500. Поворачиваем его на 45 градусов и получаем размеры 636.4 на 636.4, а квадрат со сторонами 450 на 450, при том же угле, дает те же самые 636.4 на 636.4.
То есть, при одинаком угле поворота и конечных размерах, мы имеем разные базовые размеры.

Ок, спасибо. Это, пожалуй, самый убедительный пример...

Ну и... я не знаю... но это как-то "не честно" со стороны флеша не давать полную информацию о клипе. Это, конечно, не баг, но очень неприятная фича... Как-то не по-людски, это, вобщем... Ведь, если подумать, если бы я знал исходные, а не вычисленные размеры - я бы и сам смог легко их вычислить, а вот наоборот - никак. =\

ЗЫ. Даже не знаю... есть большое желание написать в Адоби по этому поводу... как считаете, стоит?

iNils
16.01.2008, 12:30
в вершины мувиклипы всунуть, да и всё.Я еще понимаю вопрос wvxvw, ну крутил, вертел, сжимал человек объект и вдруг захотел узнать первоначальные его размеры, а описать это в свойствах при создании или же сделать сброс параметров, лень. Но тратить время на расстановку мувиклипов в вершинах, это тоже самое, что варить рис по одной рисенке.

Ведь, если подумать, если бы я знал исходные, а не вычисленные размеры - я бы и сам смог легко их вычислить, а вот наоборот - никак. =\Если подумать, то эти вычисления более трудозатратны, чем спрять объект, вернуть ему исходные пропорции и угол, снять размеры и верунть все на место.
Другой вопрос, что нет свойств, возращающие исходные размеры объекта.

А вообще, для чего это нужно? Может есть другое решение для задачи, породившей этот вопрос.

wvxvw
16.01.2008, 13:49
import flash.geom.Matrix;
import mx.transitions.Transition;
import mx.transitions.TransitionManager;
import flash.display.BitmapData;
//
class PixelRotate extends Transition {

//public var type:Object = PixelRotate;
public var className:String = "PixelRotate";

private var _cellW:Number = 5;
private var _cellH:Number = 5;
private var __w:Number;
private var __h:Number;
private var __x:Number;
private var __y:Number;
private var __d:Number;
private var __mtx:Matrix;
private var __betha:Number;
private var _mask:MovieClip;
private var _bmp_arr:Array = [];
private var _flt_arr:Array = [];

function PixelRotate (content:MovieClip, transParams:Object, manager:TransitionManager) {
this.init (content, transParams, manager);
};

function init (content:MovieClip, transParams:Object, manager:TransitionManager):Void {
super.init (content, transParams, manager);
this._cellW = transParams.xSections || 5;
this._cellH = transParams.ySections || 5;
this.__mtx = content.transform.matrix.clone();
var last_rot:Number = content._rotation;
content._rotation = 0;
this._flt_arr = content.filters;
// ! вот, тут это нужно
this.__w = Math.ceil(content._width*100/content._xscale);
this.__h = Math.ceil(content._height * 100 / content._yscale);
content._rotation = last_rot;
this.__x = Math.floor(this.__w / this._cellW);
this.__y = Math.floor(this.__h / this._cellH);
this.__d = Math.sqrt(this.__x*this.__x + this.__y*this.__y) / 2;
this.__betha = Math.atan(this.__x / this.__y);
_bmp_arr = [];
for (var i:Number = Math.floor(this.__x/2); i <= this.__w; i += this.__x) {
this._bmp_arr.push([]);
for (var j:Number = Math.floor(this.__y / 2); j <= this.__h; j += this.__y) {
var bmpd:BitmapData = new BitmapData(this.__x, this.__y);
var mtx:Matrix = new Matrix();
mtx.translate(this.__x / 2 - i, this.__y / 2 - j);
bmpd.draw(content, mtx);
this._bmp_arr[this._bmp_arr.length-1].push(bmpd);
}
}
};

private function _render (p:Number):Void {
if (!this._mask) {
this._mask = content._parent.createEmptyMovieClip('_PixelRotateMask', content._parent.getNextHighestDepth());
var mtx:Matrix = this.__mtx.clone();
_mask.transform.matrix = mtx;
_mask.filters = this._flt_arr;
content._visible = false;
//content._alpha = 50;
}
//
this._mask.clear();
var ii:Number = 0;
var jj:Number = 0;
for (var i:Number = Math.floor(this.__x / 2); i <= this.__w; i += this.__x, ii++) {
jj = 0;
for (var j:Number = Math.floor(this.__y / 2); j <= this.__h; j += this.__y, jj++) {
this._drawRotatedRectangle(this._mask, i, j, this.__d*p, Math.PI*2*p, ii, jj, p);
}
}
};

private function _drawRotatedRectangle(mc:MovieClip, x:Number, y:Number, d:Number, r:Number, i:Number, j:Number, p:Number):Void {
var mtx:Matrix = new Matrix();
mtx.rotate(Math.PI * 2 - r);
mtx.scale(p, p);
mtx.translate(x - d * Math.sin(r - this.__betha), y - d * Math.cos(r - this.__betha));
//mc.lineStyle(1, 0xff, 100);
mc.beginBitmapFill(this._bmp_arr[i][j], mtx);
mc.moveTo(x - d * Math.sin(r - this.__betha), y - d * Math.cos(r - this.__betha));
mc.lineTo(x - d * Math.sin(r + this.__betha), y - d * Math.cos(r + this.__betha));
mc.lineTo(x - d * Math.sin(r + Math.PI - this.__betha), y - d * Math.cos(r + Math.PI - this.__betha));
mc.lineTo(x - d * Math.sin(r + Math.PI + this.__betha), y - d * Math.cos(r + Math.PI + this.__betha));
mc.endFill();
}

function cleanUp ():Void {
super.cleanUp();
for (var i:Number = 0; i < this._bmp_arr.length; i++) {
for (var j:Number = 0; j < this._bmp_arr[i].length; j++) {
this._bmp_arr[i][j].dispose();
}
}
_bmp_arr = [];
this._mask.removeMovieClip();
content._visible = true;
};
}
Это не конечный вариант, но смысл, я думаю, понятен.
Другой вопрос, что нет свойств, возращающие исходные размеры объекта.
Вот именно это мне тож не нравится.

etc
16.01.2008, 14:32
Олежек, опять ты свою клинопись выложил… :D

wvxvw
16.01.2008, 16:33
Эсли присмотришься по-внимательнее, ето вобщем-то написано точно так же, как и все остальные транзишнс... А если не нравятся имена переменных... ну, даж нинаю, если прям такое отвращение - я думаю, можно файнд-анд-риплейсом заменить...
Да и вообще, вопрос уж явно был не об этом =/

Ostgur
16.01.2008, 16:51
Variable suffix (http://livedocs.adobe.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001151.html)

wvxvw
16.01.2008, 17:00
Использование суффиксов - это рекомендация, и, коль скоро компилятор не обязывает их использовать, этого можно не делать, если мне так больше нравится...
И вообще, речь не о том, как красивше писать код -- если так угодно, я могу и фрактурой Вальбаума его написать, смысл от этого не поменяется.

telit
16.01.2008, 17:38
красиво писать никак не получается особенно когда в голове есть свежая мысля :)

iNils
16.01.2008, 20:55
Это не конечный вариант, но смысл, я думаю, понятен.И что с этим делать надо?

wvxvw
16.01.2008, 21:31
И что с этим делать надо?
import mx.transitions.*;
import mx.transitions.easing.*;
import PixelRotate;
//
var d:Transition = TransitionManager.start (_mc, {type:PixelRotate, xSections:8, ySections:6, duration:500});

iNils
16.01.2008, 22:05
путь.getBounds (тут ничего не надо)

wvxvw
16.01.2008, 23:18
изваяю памятник при жизни %)