2
$\begingroup$

I would like to know how can I generate a collection of random 2D closed smooth curves.

I thought about generating a random 3D surface with random peaks, and then intersecting the Z=0 plane with it, and extract the largest contour, for example. I just not sure how to do it practically... it is the correct way? I would love to get some guidance.

I am looking for a result in this fashion:

enter image description here

$\endgroup$
  • $\begingroup$ It will be better if one can somehow control the shape. $\endgroup$ – Pu Zhang Aug 12 at 1:30
  • 4
    $\begingroup$ Another method would be to use Bézier curves. You could start off approximating a circle by a Bézigon with $n$ vertices, and then distort this by randomly moving the vertices and control points. I'm not sure how to do this, but I imagine Google will be of help. $\endgroup$ – torbonde Aug 12 at 8:05
  • $\begingroup$ Catmull-Rom splines are closed curves when the start and endpoints are the same. So you can get a random closed curve by randomly generating points on the plane and then interpolating them with Catmull-Rom. $\endgroup$ – user14717 Aug 13 at 13:13
  • $\begingroup$ @user14717, could you expand your comment as an answer? $\endgroup$ – nicoguaro Aug 15 at 15:10
7
$\begingroup$

Since your figure is a closed loop, its parametric curves $x(t)$ and $y(t)$ must be periodic functions. This suggests one way to generate such figures, by constructing random smooth periodic functions $x(t)$ and $y(t)$ via summation of sinusoids/harmonics with randomized amplitude and phase. Unfortunately, it would be difficult to guarantee such a figure didn't self intersect.

But a nearby idea would be to switch to polar coordinates, and think about circle-like figures whose radius $r(t)$ is a function of the polar angle $t$. The closed loop condition requires that $r(t)$ is periodic, and you can use the same sort of sum-of-harmonics procedure to generate a random smooth periodic $r(t)$. If you "bias" this $r(t)$ by adding some constant term (larger than the sum of your randomized amplitudes), you'll get non-intersecting figures.

Some matlab code that implements this idea:

clear all
close all

% Randomize amplitude and phase.
H = 10;
rho = rand(1,H) .* logspace(-0.5,-2.5,H);
phi = rand(1,H) .* 2*pi;

% Accumulate r(t) over t=[0,2*pi]
t = linspace(0,2*pi,101);
r = ones(size(t));
for h=1:H
  r = r + rho(h)*sin(h*t+phi(h));  
end

% Reconstruct x(t), y(t)
x = r .* cos(t);
y = r .* sin(t);

% Plot r(t) vs t
figure;
plot(t,r,'r-');
xlabel('t, radians');
ylabel('r(t)');

% Plot x(t) and y(t)
figure;
hold on;
plot(0,0,'ko');
plot(cos(t),sin(t),'k--');
plot(x,y,'b-');
xlabel('x(t)');
ylabel('y(t)');
axis equal;

And here's some example (randomized) output:

Randomized r(t) Corresponding x(t) and y(t)

It should be straightforward to implement the same idea using python + numpy + matplotlib.

| cite | improve this answer | |
$\endgroup$
2
$\begingroup$

What I ended up doing is to download thousands of random images, smooth them with a Gaussian filter, and extract contours at different levels. I took 2-3 closed contours from each blurred image and packed them all into a collection of curves. My MATLAB code is available here:

https://github.com/xenomarz/smooth-curves-generator

However, you will have to gather images by yourself, one option is to use:

https://github.com/hardikvasa/google-images-download.

enter image description here

| cite | improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.