如何在 AS3 中找到旋转椭圆的紧密配合、轴对齐的边界框?

发布于 2024-08-18 06:10:15 字数 955 浏览 7 评论 0原文

AS3 getBounds 函数返回一个与旋转椭圆不紧密配合的矩形。相反,它根据矩形的边界返回一个轴对齐的矩形,该矩形的宽度/高度对应于椭圆的最大/最小直径并遵循其旋转。

Stack Overflow 上类似问题的答案优雅地概述了我的问题的数学部分:

关于椭圆和边界框的数学的 Stack Overflow 问答

基于此,我尝试在 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);

The AS3 getBounds function returns a rectangle that is not fitting tightly to a rotated ellipse. Instead it returns an axis-aligned rectangle based on the bounds of a rectangle whose width/height corresponds to the max/min diameter of the ellipse and follows its rotation.

The answer to a similar question on Stack Overflow elegantly outlines the math part of my question:

Stack Overflow Q/A about the math of ellipses and bounding boxes

Based on this I took a stab at coding a solution in AS3. So far I have been able to produce a rectangle that fits perfectly along the x-axis, but as I rotate my ellipse it acts very weird along the y-axis. Rather than alternating between 2*r_min and 2*r_max while rotating, it alternates between 2*r_min and 0. My best guess is that I have done something wrong when solving the differentiated t for gradient -> infinity...

Here is an example from my code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

美羊羊 2024-08-25 06:10:15

我认为 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));

I assumed atan(x) and cot(x) were interchangeable - turns out they're not. Who would've thought ;)

My working AS3 code ended up looking like this:

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));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文