我目前正在尝试构建一种饼图/ voronoi图混合(在canvas / javascript中)。我不知道它是否可能。我对此很新,我还没有尝试任何方法。
假设我有一个圆圈,以及一组数字2,3,5,7,11。
我想将圆圈细分为与数字相当的部分(很像饼图),但形成格子/蜂窝状的形状。
这甚至可能吗?这是非常困难的,特别是对于那些只做过一些基本饼图渲染的人来说?
答案 0 :(得分:0)
这是我对此的看法,快速浏览一下。
一般解决方案,假设n
多边形具有k
个顶点/边,将取决于n
方程的解,其中每个方程不超过{{ 1}},(但确切地说是2nk
非零)变量。每个多边形方程中的变量是相同的2k
和x_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_nk
和x_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的过渡。