如何将形状细分为给定大小的部分

时间:2012-07-28 14:29:46

标签: javascript math graphics graph charts

我目前正在尝试构建一种饼图/ voronoi图混合(在canvas / javascript中)。我不知道它是否可能。我对此很新,我还没有尝试任何方法。

假设我有一个圆圈,以及一组数字2,3,5,7,11。

我想将圆圈细分为与数字相当的部分(很像饼图),但形成格子/蜂窝状的形状。

enter image description here

这甚至可能吗?这是非常困难的,特别是对于那些只做过一些基本饼图渲染的人来说?

3 个答案:

答案 0 :(得分:0)

这是我对此的看法,快速浏览一下。

一般解决方案,假设n多边形具有k个顶点/边,将取决于n方程的解,其中每个方程不超过{{ 1}},(但确切地说是2nk非零)变量。每个多边形方程中的变量是相同的2kx_1, x_2, x_3... x_nk变量。恰好有四个y_1, y_2, y_3... y_nk具有非零系数,并且恰好四个x_1, x_2, x_3... x_nk具有每个多边形方程的非零系数。 y_1, y_2, y_3... y_nkx_i根据父形状的不同而有所不同。为简单起见,我们假设形状为圆形。边界条件是:y_i

注意:我说的不超过(x_i)^2 + (y_i)^2 <= r^2,因为我不确定下限,但知道它不能超过2nk。这是多边形的结果,作为要求,共享顶点。

方程式是定义但可变有界的积分的集合,表示每个多边形的面积,面积等于2nk多边形:

ith

其中A_i = pi*r^2/S_i是父圆的半径,r是分配给多边形的数字,如图所示。

四个独立的S_i对,在多边形方程中都具有非零系数,将产生多边形的顶点。

这可能相当困难。

答案 1 :(得分:0)

边界是否从头开始固定,或者你可以稍微变形吗?

如果我必须解决这个问题,我会将这些区域从大到小排序。然后,从最大的区域开始,我将首先生成具有所需大小的随机凸多边形(沿着圆的顶点)。下一个区域将与第一个区域共享边缘,但在其他方面也将是随机和凸起的。之后的每个多边形将从已存在的多边形中选择现有边,并且还将共享从那里开始的任何“凸”边缘(其中“凸边”是一个,如果用于新多边形,将导致新的多边形)多边形仍然是凸的。)

通过评估“总边界接近所需边界”的不同预期多边形位置,您可以生成一个廉价的近似初始目标。这与字云的作用非常相似:在尝试填充或多或少的封闭空间时,将事物从大到小逐渐放置。

答案 2 :(得分:0)

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

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的过渡。