Reputation: 909
I have an svg circle element with coordinate attribute as below:
<circle id="c1" class="area" cx="440" cy="415" r="75"></circle>
I would like to generate some random points within the circle element by using javascript or d3. I thought about the right approach to apply. And I come to the conclusion that I can do it in 2 ways:
by generate just n random point coordinates cx,cy and then check if each point is within the svg circle if the distance from it to the center is at most the radius of circle element.
by generate the radius of the point as R * sqrt(random())
and the theta as random() * 2 * PI
and calculate cx,cy as r * cos(theta)
and r * sin(theta)
.
Is there a better approach?
Upvotes: 2
Views: 1955
Reputation: 33024
I'm using @Joseph O'Rourke idea to draw 1500 points. Alternatively you may create a single circle and reuse it.
Also if you don't need to use those points you may consider svg patterns
const SVG_NS = "http://www.w3.org/2000/svg";
let R = 50;
let c = { x: 50, y: 50 };
let g = document.createElementNS(SVG_NS, "g");
for (let i = 0; i < 1500; i++) {
let a = Math.random() * 2 * Math.PI;// angle
let r = Math.sqrt(~~(Math.random() * R * R));// distance fron the center of the main circle
// x and y coordinates of the particle
let x = c.x + r * Math.cos(a);
let y = c.y + r * Math.sin(a);
// draw a particle (circle) and append it to the previously created g element.
drawCircle({ cx: x, cy: y, r: 1 }, g);
}
function drawCircle(o, parent) {
var circle = document.createElementNS(SVG_NS, "circle");
for (var name in o) {
if (o.hasOwnProperty(name)) {
circle.setAttributeNS(null, name, o[name]);
}
}
parent.appendChild(circle);
return circle;
}
//append the g element to the svg
svg.appendChild(g);
svg {
border: 1px solid;
max-width: 90vh;
}
<svg id="svg" viewBox="0 0 100 100"></svg>
Upvotes: 5
Reputation: 4406
Your second method does not produce a uniform distribution inside the circle. See the left image below.
This process goes under the name "disk point-picking." See that article to achieve the right image below
Upvotes: 3