将不同大小的矩形拟合成圆形的优雅算法是什么?
我有一堆大小可变的矩形,我需要将它们粗略地拼成一个圆,大概最大的矩形位于中心。
注意。圆圈没有固定的大小——这只是我所追求的整体形状。
这更像是我想象的一个懒惰的人类包装(一旦一块就位,它就会留下来。)
它们已经按照宽度和高度的最大值进行排序,最大的在前。
理想情况下——我认为这可以通过订购来保证——根本不会有任何间隙。
我正在努力解决的算法是:
for each rectangle:
if first:
place rectangle at origin
add all edges to edge list
else:
for each edge in edge list:
if edge is long enough to accomodate rectangle (length <= width or height depending on orientation):
if rectangle placed on this edge does not collide with any other edges:
calculate edge score (distance of mid-point from origin)
use edge with lowest edge score
place rectangle on edge
for each of this rectangles edges:
if edge overlaps one already in the edge list:
merge or remove edge
else:
add to edge list
remove used edge from edge list
add unused sections of this edge into edge list
这对于前几个矩形来说效果很好,但是边缘合并非常复杂,我当前选择使用边缘的哪一部分(一端或另一端)的方法往往会留下很多差距。
虽然我认为我最终会让这个方法相当令人满意地工作,但感觉我缺少一个更优雅的(图?)算法。
I have a bunch of rectangles of variable size which I need to fit together roughly into a circle, presumably with the largest ones at the center.
NB. The circle is not of a fixed size - that's just the overall shape I'm after.
This is more like how I'd imagine a lazy human packs (once a piece is in place, it stays.)
They are already ordered by the maximum of their width and height, largest first.
Ideally - and I think this can be guaranteed by the ordering - there would be no gaps at all.
The algorithm I'm struggling with is:
for each rectangle:
if first:
place rectangle at origin
add all edges to edge list
else:
for each edge in edge list:
if edge is long enough to accomodate rectangle (length <= width or height depending on orientation):
if rectangle placed on this edge does not collide with any other edges:
calculate edge score (distance of mid-point from origin)
use edge with lowest edge score
place rectangle on edge
for each of this rectangles edges:
if edge overlaps one already in the edge list:
merge or remove edge
else:
add to edge list
remove used edge from edge list
add unused sections of this edge into edge list
This works alright for the first few rectangles, but the edge merging is pretty hairy and my current method of choosing which section of an edge to use (one end or the other) tends to leave lots of gaps.
Although I think I'd eventually get this method working fairly satisfactorily, it feels like there's a far more elegant (graph?) algorithm that I'm missing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
“按大小排序”是什么意思 - 长度或面积?我想它必须按最大长度排序。
如何“找到最接近原点且有矩形空间的边缘”?据我了解该任务,您有按长边长度排序的矩形。您将最长的放置在原点。
<循环>
然后,取出剩余矩形中最长的一个,并将其放置在第一个矩形的长边/矩形堆的最长边上。您可能不会将其放置在边缘的中间,而是将第二个矩形的一个角放置在第一个矩形的一个角上。
作为一项规则,我建议始终使用最长剩余边缘的西端或北端(根据您的喜好)。也许总是选择边缘较长的角会更好。
这样你就得到了一条新的边,它将矩形所附着的角拉直,这现在可能是剩余的最长边。
你就是这么做的吗?问题出在哪里?您有不想要的结果的图片吗?
好吧,在看到你的例子后,现在有一些伪Python:
我希望,这使我的推理更加透明。这种方法应该不会给你带来间隙和碰撞,因为我认为它会产生或多或少的凸形(不确定)。
What do you mean "ordered by size" - length or area? I suppose it must be sorted by max length.
How do you "find the edge closest to the origin which has space for rectangle"? As far as I understand the task, you have rectangles sorted by the length of their longer side. You place the longest one at the origin.
<Loop>
Then you take the longest of the remaining rectangles and place it on the long side of the first one / the longest edge of the pile of rectangles. Probably you will place it not in the middle of the edge, but with one corner of the second on one corner of the first rectangle.
As a rule I suggest to always use the west or north end of the longest remaining edge (as you like). Maybe it's even better to always choose the corner with the longer edge.
So you get a new edge, that straightens the corner to which the rectangle has been attached, which now might be the longest remaining edge.
</Loop>
Is that what you do? And what seems to be the problem? Do you have a picture of an unwanted result?
Ok, after seeing your example now here some pseudo-python:
I hope, that makes my reasoning more transparent. This approach should give you no gaps and no collisions, since I reckon that it produces a more or less convex shape (not sure).
您能否详细说明一下
1. 围绕中心相当均匀?
2. 目标是什么?即,您是否想要最大化可容纳的矩形数量,或者您知道所有矩形都适合并且您希望最大程度地减少空间浪费?
我不知道一个懒惰的人会如何收拾行李。但如果我想优化包装,我会从角落开始,然后来到中心。
Can you please elaborate more on
1. pretty evenly around the center?
2. what is the goal? i.e. do you want to maximize the number of rectangles that can fit or you know that all of them will fit and you want to minimize the wastage of space?
I am not sure how a lazy human will pack. But if I wan to optimize the packing, I will start from the corners and then come to the center.