我想生成所有間距相同的點數,但仍保持隨機性。隨機生成的點將顯示在矩形畫布上。目前我只是用Math.random()
產生每個點。我已經嘗試過測試每個點相對於其他點的間距,但是我不知道如何使這個點的點數達到x
。隨機生成具有相似間距的點
我應該如何去產生這些點?
我想生成所有間距相同的點數,但仍保持隨機性。隨機生成的點將顯示在矩形畫布上。目前我只是用Math.random()
產生每個點。我已經嘗試過測試每個點相對於其他點的間距,但是我不知道如何使這個點的點數達到x
。隨機生成具有相似間距的點
我應該如何去產生這些點?
可以通過將區域劃分成相等大小的網格,在每個網格放置點隨機地使用半隨機分佈。但是您需要知道您將添加多少點,否則將無法工作。
演示比較隨機和加權分佈的結果。現實情況是隨着點數的增加,隨機函數將產生更均勻的分佈。點擊畫布以加倍點數並比較隨機和加權的結果。
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);
}
canvas {
border : 2px black solid;
}
<canvas id="canvas" width = 256 height = 256></canvas>
<canvas id="canvas1" width = 256 height = 256></canvas>
<div>Click canvas to increase point count</div>
你可以使用類似下一種方法(僞代碼)。
點與正方形網格的節點相連,並具有一些隨機位移。
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
由於雙方@MBo & @ 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++;
}
}
視覺示範
前:
後:
「間隔均勻,同時仍保持隨意性」:這是矛盾的,請詳細說明您的要求。 –