Как найти в AS3 плотно прилегающую, выровненную по оси ограничительную рамку вращающегося эллипса? - PullRequest
2 голосов
/ 16 января 2010

Функция AS3 getBounds возвращает прямоугольник, который не плотно прилегает к повернутому эллипсу. Вместо этого он возвращает выровненный по оси прямоугольник на основе границ прямоугольника, ширина / высота которого соответствует максимальному / минимальному диаметру эллипса и следует его вращению.

Ответ на аналогичный вопрос о переполнении стека изящно обрисовывает математическую часть моего вопроса:

Переполнение стека Q / A о математике эллипсов и ограничительных рамок

Исходя из этого, я попытался кодировать решение в AS3. До сих пор я был в состоянии создать прямоугольник, который идеально подходит вдоль оси X, но когда я вращаю свой эллипс, он действует очень странно вдоль оси Y. Вместо чередования между 2 * r_min и 2 * r_max при вращении он чередуется между 2 * r_min и 0. Мое лучшее предположение состоит в том, что я сделал что-то не так при решении дифференцированного t для градиента -> бесконечность ...

Вот пример из моего кода:

var r_max:uint = 45;
var r_min:uint = 20;
var rot:Number = ellipse.rotation * (Math.PI / 180);
var t_nil:Number = Math.atan( -r_min * Math.tan(rot) / r_max);
var t_inf:Number = Math.atan(r_min * Math.atan(rot) / r_max) + (Math.PI / 2);
var x:Number = r_max * Math.cos(t_nil) * Math.cos(rot) - r_min * Math.sin(t_nil) * Math.sin(rot);
var y:Number = r_min * Math.sin(t_inf) * Math.cos(rot) + r_max * Math.cos(t_inf) * Math.sin(rot);

1 Ответ

2 голосов
/ 20 января 2010

Я предположил, что atan (x) и cot (x) взаимозаменяемы - оказывается, что нет. Кто бы мог подумать;)

Мой рабочий код AS3 в итоге выглядел так:

var r_max:uint = 45;
var r_min:uint = 20;
var rot:Number = ellipse.rotation * (Math.PI / 180);
var t_nil:Number = Math.atan( -r_min * Math.tan(rot) / r_max);
var t_inf:Number = Math.atan(r_min * (Math.cos(rot) / Math.sin(rot)) / r_max);
var rect_width:Number = 2 * (r_max * Math.cos(t_nil) * Math.cos(rot) - r_min * Math.sin(t_nil) * Math.sin(rot));
var rect_height:Number = 2* (r_min * Math.sin(t_inf) * Math.cos(rot) + r_max * Math.cos(t_inf) * Math.sin(rot));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...