随机生成间距相近的点

时间:2017-05-12 01:38:45

标签: javascript canvas random geometry

我希望生成x个数量的点,这些点都是相同的间隔,同时仍然保持随机性。随机生成的点将显示在矩形画布上。目前,我只是使用Math.random()生成每个点。我已尝试测试与其他点相关的每个点的间距,但我不知道如何使用x点数来完成此工作。

我应该如何产生这些要点?

3 个答案:

答案 0 :(得分:1)

你可以使用下一种方法(伪代码)。

点与方格的节点相关联,并且有一些随机位移。

for iy in rowcountrange
    for ix in columncountrange
        points[iy, ix].X = ix * spacing + (random(0..1) - 0.5) * spacing
        points[iy, ix].Y = iy * spacing + (random(0..1) - 0.5) * spacing

答案 1 :(得分:1)

您可以通过将区域划分为相等大小的网格并在每个网格中随机放置一个点来使用半随机分布。但是你需要知道你将添加多少分,否则它将无效。

该演示比较了随机和加权分布的结果。实际情况是随着点数的增加,随机函数将产生更均匀的分布。单击画布使点数加倍并比较随机和加权的结果。



const ctx = canvas.getContext("2d");
const ctx1 = canvas1.getContext("2d");
const w = canvas.width;
const h = canvas.height;
canvas.addEventListener("click",drawPoints);
canvas1.addEventListener("click",drawPoints);

function randomPoint(){
    const xx = Math.floor(Math.random() *  w);
    const yy = Math.floor(Math.random() *  h);
    ctx1.fillRect(xx,yy,pointSize,pointSize);
}
function randomPointOf(n, ofM){
    const spread = Math.sqrt(ofM);
    const xs = w / spread; // x spacing
    const ys = h / spread; // y spacing
    n = n % ofM;
    const x = (n % spread) * xs;
    const y = (Math.floor(n / spread)) * ys;
    const xx = Math.floor(Math.random() *  xs + x);
    const yy = Math.floor(Math.random() *  ys + y);
    ctx.fillRect(xx,yy,pointSize,pointSize);
}

function randomPoints(pointCount, distrabutionCount){
    var i;
    for(i = 0; i < pointCount; i ++){
        randomPointOf(i,distrabutionCount); // do distrubuted random
        randomPoint(); // do random
    }
 }
var pointCount = 100;
var pointSize = 1
ctx.font = ctx1.font = "12px arial";
ctx1.fillStyle = ctx.fillStyle = "black";
ctx1.strokeStyle = ctx.strokeStyle = "white";
ctx1.lineWidth = ctx.lineWidth = 3;
drawPoints();
function drawPoints(){
    ctx.clearRect(0,0,w,h);
    ctx1.clearRect(0,0,w,h);
    pointCount *= 2;
    if(pointCount > w * h){
       pointCount = 100;
    }
    pointSize = pointCount < 1600 ? 2 : 1;
    randomPoints(pointCount,100);
    ctx.strokeText("Weighted. "+ pointCount + " points",10,14);
    ctx1.strokeText("Random. "+ pointCount + " points",10,14);
    ctx.fillText("Weighted. "+ pointCount + " points",10,14);
    ctx1.fillText("Random. "+ pointCount + " points",10,14);
}    
    
&#13;
canvas {
   border : 2px black solid;
}
&#13;
<canvas id="canvas" width = 256 height = 256></canvas>
<canvas id="canvas1" width = 256 height = 256></canvas>
<div>Click canvas to increase point count</div>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

感谢@MBo&amp; @ Blindman67。我使用了将画布划分为网格的想法,每个点都需要一个图块。确定网格的尺寸需要基于以下等式的一些简单代数:

rows * columns = x
rows / columns = canvasHeight / canvasWidth

使用它我可以为行和列创建公式:

rows = ((canvasHeight * x) / canvasWidth)^(1/2)
columns = x / ((canvasHeight * x) / canvasWidth)^(1/2)

以下是我实现代码的方法:

var x = 100; // number of points
var points = [];

// determine increment for grid
var yIndex = canvas.height / Math.round(Math.sqrt((canvas.height * x) / canvas.width));
var xIndex = canvas.width / Math.round(x / Math.sqrt((canvas.height * x) / canvas.width));

// generate points randomly across grid
var k = 0;
for (var y = 0; y < this.canvas.height; y+=yIndex) {
    for (var x = 0; x < this.canvas.width; x+=xIndex) {
        points[k] = [
            getRandomArbitrary(x,x+xIndex),
            getRandomArbitrary(y,y+yIndex),
        ];
        k++;
    }
}

视觉演示

在:

before

后:

after