I'm trying to generate random blob shapes in canvas. I am able to do so generating points in a circle whose values are multiplied by a random factor then using a cardinal spline to connect them. It works okay, but sometimes the spline will overlap itself or the angle between the points will be too acute.
How can I prevent this from occurring? Thank you!
const random = (min, max) => {
if (max == null) {
max = min;
min = 0
}
if (min > max) {
var tmp = min;
min = max;
max = tmp
}
return min + (max - min) * Math.random()
}
const randomShape = (x, y, size) => {
let points = []
let numPoints = 20
let slice = (Math.PI * 2) / numPoints
let minRadius = random(15, size * 0.5)
let maxRadius = random(15, size * 0.5)
let startAngle = random(Math.PI * 2)
for (let i = 0; i < numPoints; i++) {
let angle = startAngle + i * slice
points.push(Math.floor(x + Math.cos(angle) * random(minRadius, maxRadius)),
Math.floor(y + Math.sin(angle) * random(minRadius, maxRadius)))
}
return {
x: x,
y: y,
points: points
}
}
If you connect your points with straight lines, you will find that your polyline will self-intersect or (almost) overlap. This means that the spline overlapping issue is not caused by the cardinal spline interpolation issue but an issue with your data points.
If we look at your codes, we will find that the X and Y coordinates of the data points are calculated as
X= Math.floor(x + Math.cos(angle) * random(minRadius, maxRadius))
Y= Math.floor(y + Math.sin(angle) * random(minRadius, maxRadius))
This also means that your X and Y values are computed based on different values for "radius" and this is likely the reason for the problem with your data points. So, the change is simply to make 1 call to random() function per each point.