Versuchen Sie this paper. Es hat einen schönen, intuitiven Algorithmus, der das tut, was Sie brauchen.
In unserer Modellbildung haben wir ein anderes Modell übernommen: Wir betrachten jedes Zentrum als eine repulsive Kette, die mit allen seinen Nachbarn in Beziehung steht.
Zu Beginn der Simulation sind die Zentren zufällig verteilt, ebenso die Stärken der Strings. Wir wählen zufällig ein Zentrum; dann berechnen wir die resultierende Kraft, die von allen Nachbarn des gegebenen Zentrums verursacht wird, und wir berechnen die Verschiebung, die proportional und orientiert im Sinne der resultierenden Kraft ist.
Nach einer bestimmten Anzahl von Iterationen (die von der Anzahl der Zentren und dem Grad der anfänglichen Zufälligkeit abhängt) wird das System stabil.
Falls aus den Abbildungen nicht ersichtlich ist, erzeugt dieser Ansatz gleichmäßig verteilte Punkte. Sie können stattdessen eine Kraft verwenden, die innerhalb Ihrer Grenzen Null ist (z. B. zwischen 2 und 3) und nicht Null (sonst abstoßend, wenn die Punkte zu nahe liegen, attraktiv, wenn zu weit).
Dies ist meine Python-Implementierung (sorry, ich weiß nicht Ruby). Importieren Sie dies einfach und rufen Sie uniform() auf, um eine Liste von Punkten zu erhalten.
import numpy as np
from numpy.linalg import norm
import pylab as pl
# find the nearest neighbors (brute force)
def neighbors(x, X, n=10):
dX = X - x
d = dX[:,0]**2 + dX[:,1]**2
idx = np.argsort(d)
return X[idx[1:11]]
# repulsion force, normalized to 1 when d == rmin
def repulsion(neib, x, d, rmin):
if d == 0:
return np.array([1,-1])
return 2*(x - neib)*rmin/(d*(d + rmin))
def attraction(neib, x, d, rmax):
return rmax*(neib - x)/(d**2)
def uniform(n=25, rmin=0.1, rmax=0.15):
# Generate randomly distributed points
X = np.random.random_sample((n, 2))
# Constants
# step is how much each point is allowed to move
# set to a lower value when you have more points
step = 1./50.
# maxk is the maximum number of iterations
# if step is too low, then maxk will need to increase
maxk = 100
k = 0
# Force applied to the points
F = np.zeros(X.shape)
# Repeat for maxk iterations or until all forces are zero
maxf = 1.
while maxf > 0 and k < maxk:
maxf = 0
for i in xrange(n):
# Force calculation for the i-th point
x = X[i]
f = np.zeros(x.shape)
# Interact with at most 10 neighbors
Neib = neighbors(x, X, 10)
# dmin is the distance to the nearest neighbor
dmin = norm(Neib[0] - x)
for neib in Neib:
d = norm(neib - x)
if d < rmin:
# feel repulsion from points that are too near
f += repulsion(neib, x, d, rmin)
elif dmin > rmax:
# feel attraction if there are no neighbors closer than rmax
f += attraction(neib, x, d, rmax)
# save all forces and the maximum force to normalize later
F[i] = f
if norm(f) <> 0:
maxf = max(maxf, norm(f))
# update all positions using the forces
if maxf > 0:
X += (F/maxf)*step
k += 1
if k == maxk:
print "warning: iteration limit reached"
return X
Wie ist das eine Programmierfrage? Es ist eine Frage "Sag mir einen Algorithmus" ... –
Programmierung ist sehr auf Algorithmen bezogen. –
@Mitch Hast du die letzte Zeile gelesen? Du siehst heute eher mürrisch aus. :/ – marcog