如何更好地为 3D 画廊打包与球体相切的矩形?
我正在使用 ActionScript 3 和 Flash 10 3D (2.5D) API 创建 3D 球体图库。我找到了一种有效但并不理想的方法。我想看看是否有更好的方法。
我的算法是这样的:
Let n = the number of images h = the height of each image w = the width of each image
- 通过假设(错误地)图像的表面积等于我们想要创建的球体的表面积来近似圆的半径。
计算半径求解r
在nwh = 4πr2
中。这是需要改进的部分。 - 计算行之间的角度。
rowAngle = 2atan(h / 2 / r)
。 - 计算行数。
rows = Floor(π / rowAngle)
。 - 由于第一步是近似值,因此行数不会完全适合,因此为了演示,请添加填充 rowAngle。
rowAngle += (π - rowAngle * rows) / rows
。 对于
行
中的每个i
:- 计算该行纬度圆的半径。
latitudeRadius = radius * cos(π / 2 - rowAngle * i
。 - 计算列之间的角度。
columnAngle = atan(w / 2 / latitudeRadius) * 2
。 - 计算列数。
columns = Floor(2 * π / columnAngle)
- 由于第一步是近似值,因此列数不会完全适合,因此为了演示,请向 columnAngle 添加填充。
columnAngle += (2 * π - columnAngle * column) / column
. - 对于
列
中的每个j
,沿Z轴平移-radius
,旋转π / 2 + rowAngle * i< /code> 绕 X 轴旋转,
columnAngle * j
绕 Y 轴旋转。
- 计算该行纬度圆的半径。
要查看其实际效果,单击此处。备用链接 请注意,使用默认设置时,球体中实际的项目数量少了 13。我相信这是我在第一步中的近似值引入的错误。
我无法找出一种方法来确定这样一个球体的确切半径应该是多少。我希望学习一种更好的方法、正确的方法,或者我正在尝试做的事情很难或非常难(在这种情况下,我会对我所拥有的感到满意)。
I am creating a 3D sphere gallery with ActionScript 3 and the Flash 10 3D (2.5D) APIs. I have found a method that works but is not ideal. I would like to see if there is a better method.
My algorithm goes like this:
Let n = the number of images h = the height of each image w = the width of each image
- Approximate the radius of the circle by assuming (incorrectly) that the surface area of the images is equal to the surface area of the sphere we want to create.
To calculate the radius solve forr
innwh = 4πr2
. This is the part that needs to be improved. - Calculate the angle between rows.
rowAngle = 2atan(h / 2 / r)
. - Calculate the number of rows.
rows = floor(π / rowAngle)
. - Because step one is an approximation, the number of rows will not fit perfectly, so for presentation add padding rowAngle.
rowAngle += (π - rowAngle * rows) / rows
. For each
i
inrows
:- Calculate the radius of the circle of latitude for the row.
latitudeRadius = radius * cos(π / 2 - rowAngle * i
. - Calculate the angle between columns.
columnAngle = atan(w / 2 / latitudeRadius) * 2
. - Calculate the number of colums.
columns = floor(2 * π / columnAngle)
- Because step one is an approximation, the number of columns will not fit perfectly, so for presentation add padding to columnAngle.
columnAngle += (2 * π - columnAngle * column) / column
. - For each
j
incolumns
, translate-radius
along the Z axis, rotateπ / 2 + rowAngle * i
around the X axis, and rotatecolumnAngle * j
around the Y axis.
- Calculate the radius of the circle of latitude for the row.
To see this in action, click here. alternate link. Notice that with the default settings, the number of items actually in the sphere are less by 13. I believe is the error introduced by my approximation in the first step.
I am not able to figure out a method for determining what the exact radius of such a sphere should be. I'm hoping to learn either a better method, the correct method, or that what I am trying to do is hard or very hard (in which case I will be happy with what I have).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我会把这个问题分成两个相关的问题。
给定半径,如何将东西打包到球体上?
给定许多事物,如何找到正确的半径?
如果第一个问题解决了,那么第二个问题就很容易解决了。这是伪代码。
这将找到使用您的打包算法打包所需数量物品的最小半径。如果您希望可以从一个更好的起点开始 - 您当前的估计非常接近。但我不认为解析公式可以做到这一点。
现在让我们转向第一个问题。你有一个非常合理的方法。但它确实有一个严重的错误。错误是您的
columnAngle
不应该针对行的中间进行计算。您需要做的是找出您的物品最接近极点的纬度,并将其用于计算。这就是为什么当您尝试装入 10 件物品时,您会发现包装导致角重叠。如果你想要更密集的排列,你可以尝试将行压向赤道。这有时会导致连续有更多的空间容纳更多的物品,这样你就可以在更小的范围内获得更多的东西。但从视觉上看,它可能看起来不太好。尝试一下,然后决定您是否喜欢结果。
顺便说一句,我喜欢这个主意。看起来不错。
I would divide this problem into two connected problems.
Given a radius, how do you pack things on to the sphere?
Given a number of things, how do you find the right radius?
If you have a solution to the first problem, the second is easy to solve. Here it is in pseudo-code.
This will find the smallest radius that will pack the desired number of things with your packing algorithm. If you wish you could start with a better starting point - your current estimate is pretty close. But I don't think that an analytic formula will do it.
Now let's turn to the first problem. You have a very reasonable approach. It does have one serious bug though. The bug is that your
columnAngle
should not be calculated for the middle of your row. What you need to do is figure out the latitude which your items are in that is closest to the pole, and use that for the calculation. This is why when you try to fit 10 items you find a packing that causes the corners to overlap.If you want a denser packing, you can try squishing rows towards the equator. This will result in sometimes having room for more items in a row so you'll get more things in a smaller sphere. But visually it may not look as nice. Play with it, and decide whether you like the result.
BTW I like the idea. It looks nice.
就正方形而言,这似乎是一个了解半径、正方形边长和嵌入的正方形数量之间关系的近似公式。
在 this 之后,方块数为:
或
其中
如果绘制 r=1,则为a 的函数:
您可以在其中看到 a=2 的情况是 n=6 的边界,意思是立方体:
仍在努力看看它是否可以扩展到通用矩形的情况。
编辑
对于矩形,相应的公式为:
给出:
其中
假设我们想要一个一侧为另一侧一半的矩形 (b = a/2) 和一个半径为 1 的球体。
因此,数矩形作为 a 的函数得出:
您可能会在其中看到“大”边尺寸为 2 的矩形允许球体中有 10 个矩形,而“大”边尺寸为 4 的矩形仅允许 4 个矩形。
In the case of squares, it seems to be an approximate formula for knowing the relationship between the radius, the square's side and the number of squares embedded.
Following this, the number of squares is:
or
where
If you plot for r=1, as a function of a:
Where you can see the case a=2 is the boundary for n=6, meaning a cube:
Still working to see if it can be extended to the case of a generic rectangle.
Edit
For rectangles, the corresponding formula is:
which gives:
where
Let's suppose we want rectangles with one side half of the other (b = a/2) and a sphere of radius 1.
So, the number of rectangles as a function of a gives:
Where you may see that a rectangle with a "large" side of size 2 allows 10 rectangles in the sphere, while a rectangle of "large" side 4 allows only 4 rectangles.