如何将形状细分为给定大小的区域。

4
我目前正在尝试构建一种饼图/泰森多边形混合图表(在canvas/javascript中)。我不知道这是否可能。我非常新手,还没有尝试任何方法。
假设我有一个圆和一组数字2、3、5、7、11。
我想将圆分成相当于这些数字的部分(就像饼图一样),但形成类似于蜂窝状的结构。
这个是可能的吗?对于只完成了一些基本饼图渲染的人来说,这是否过于困难?

哎呀,祝你好运! - Mitya
看起来并不是不可能,但我看到了一些困难。首先,你的解决方案将不是唯一的,因此不同的人可能会给出完全不同的解决方案。另外,确保圆上的区域相同似乎会带来很多麻烦,需要进行实际的几何分析才能使其工作。你确信要使用圆吗?因为我认为正方形会更容易处理。 - bigbenbt
它不一定是一个圆 - 实际上它应该适合粗略的椭圆形状。我认为从一个圆开始并朝着其他方向移动会更容易。也许一个更角化的形状,比如六边形可能会起作用,但正方形不行。 - roryok
从感知的角度来看(也就是让人们理解和比较你所绘制的数字),这种方法的结果会比饼图更差,而饼图本身已经比柱状图更差。我建议不要使用这种方法... - tucuxi
谢谢tucuxi,但它实际上不是用于图表,而是用作标签云。每个区域代表某一类别下的文章数量。 - roryok
显示剩余3条评论
3个回答

0

这是我快速浏览后对此的看法。

一个通用解决方案,假设有 n 个具有 k 个顶点/边的多边形,将取决于解决 n 个方程的解决方案,其中每个方程的变量不超过 2nk(但恰好有 2k 个非零变量)。每个多边形方程中的变量都是相同的 x_1,x_2,x_3... x_nky_1,y_2,y_3... y_nk 变量。每个多边形方程中恰好有四个 x_1,x_2,x_3... x_nk 具有非零系数,每个多边形方程中恰好有四个 y_1,y_2,y_3... y_nk 具有非零系数。根据父形状,x_iy_i 的边界条件不同。为了简单起见,我们假设形状是圆形。边界条件是:(x_i)^2 + (y_i)^2 <= r^2

注意:我说的不超过2nk,因为我不确定下限,但知道它不会超过2nk。这是由于多边形作为要求共享顶点。

这些方程式是一组明确的、但变量有界的积分,表示每个多边形的面积,其中第 i 个多边形的面积相等:

A_i = pi*r^2/S_i

其中r是父圆的半径,S_i是分配给多边形的数字,就像您的图表中一样。

在多边形方程式中,四个单独的(x_j,y_j)对,两者都具有非零系数,将产生多边形的顶点。

这可能证明是相当困难的。


0

边界是从一开始就固定的,还是可以稍微变形一下?

如果我要解决这个问题,我会按照面积从大到小的顺序进行排序。然后,从最大的区域开始,我会首先生成一个随机凸多边形(顶点沿着圆形),大小符合要求。下一个区域将与第一个区域共享一个边缘,但也是随机和凸的。之后的每个多边形都会从已经存在的多边形中选择一个现有的边缘,并且还会共享任何从那里开始的“凸边缘”(其中“凸边缘”是指如果用于新多边形,则新多边形仍然是凸的边缘)。

通过评估“总边界接近所需边界”的不同潜在多边形位置,您可能可以生成对初始目标的廉价近似。这与词云所做的非常相似:从大到小逐步放置东西,同时尝试填充一个更或多或少封闭的空间。


0

给定一组 Voronoi 中心(即每个中心的坐标列表),我们可以计算最靠近每个中心的区域:

area[i] = areaClosestTo(i,positions)

假设这些有点不正确,因为我们没有把中心放在正确的位置。因此,我们可以通过比较面积与理想面积来计算当前集合中的误差:

var areaIndexSq = 0;
var desiredAreasMagSq = 0;
for(var i = 0; i < areas.length; ++i) {
    var contrib = (areas[i] - desiredAreas[i]);
    areaIndexSq += contrib*contrib;
    desiredAreasMagSq += desiredAreas[i]*desiredAreas[i];
}
var areaIndex = Math.sqrt(areaIndexSq/desiredAreasMagSq);

这是区域和期望区域之间差向量的向量范数。可以将其视为最小二乘拟合线的好坏程度的一种度量。

我们还想要一些蜂窝状图案,因此我们可以称之为honeycombness(positions),并获得整个事物质量的总体度量(这只是一个起点,权重或形式可以随意调整):

var overallMeasure = areaIndex + honeycombnessIndex;

然后我们有一种机制来知道猜测的准确程度,我们可以将其与修改位置的机制相结合;最简单的方法就是向每个中心的x和y坐标添加随机量。或者您可以尝试将每个点移动到面积过高的邻域,远离面积过低的邻域。

这不是一个直接的解决方案,但除了计算每个点最接近的区域之外,它需要很少的数学知识,并且易于理解。困难的部分可能是识别局部极小值并处理它们。

顺便说一句,获取该过程的起始点应该相对容易;饼图切片的质心不应该离真实值太远。

明显的优点是,您可以使用中间计算来动画显示从饼图到Voronoi的转换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接