在边界值内表面分发点 [英] Distributing points over a surface within boundries

查看:135
本文介绍了在边界值内表面分发点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我感兴趣的分发点的predefined数超过4面的表面像一个方形的一种方式(算法)。

I'm interested in a way (algorithm) of distributing a predefined number of points over a 4 sided surface like a square.

目前的主要问题是,每个点都有得有一个最小值和最大值接近对方(无规二predefined值之间)。基本上,任意两点的距离不应近于假设2,另外比3。

The main issue is that each point has got to have a minimum and maximum proximity to each other (random between two predefined values). Basically the distance of any two points should not be closer than let's say 2, and a further than 3.

我的code将用Ruby实现(该点位置,表面上是一个地图),但任何意见或片段肯定欢迎,因为我所有的想法包括蛮力相当数量。

My code will be implemented in ruby (the points are locations, the surface is a map), but any ideas or snippets are definitely welcomed as all my ideas include a fair amount of brute force.

推荐答案

尝试这纸。它有一个很好的,直观的算法,做你所需要的。

Try this paper. It has a nice, intuitive algorithm that does what you need.

在我们的模型化,我们采用了另一种模式:我们认为每个中心由一个排斥字符串与它所有的邻居

In our modelization, we adopted another model: we consider each center to be related to all its neighbours by a repulsive string.

目前的模拟开始时,中心随机分布,的以及长处   字符串。我们随机选择移动一个中心;然后我们计算所造成的全部合力   给定中心的邻居,我们计算其比例和导向位移   在所得力的感

At the beginning of the simulation, the centers are randomly distributed, as well as the strengths of the strings. We choose randomly to move one center; then we calculate the resulting force caused by all neighbours of the given center, and we calculate the displacement which is proportional and oriented in the sense of the resulting force.

在进行一定次数的迭代(它取决于数   中心和初始随机性的程度)系统变得稳定。

After a certain number of iterations (which depends on the number of centers and the degree of initial randomness) the system becomes stable.

在情况下,它是不是从这些数字清楚,这种方法产生均匀分布的点。可以使用代替的力是零的边界内(2和3之间,例如)和非零否则(斥力,如果点是太近,吸引力的,如果过远)。

In case it is not clear from the figures, this approach generates uniformly distributed points. You may use instead a force that is zero inside your bounds (between 2 and 3, for example) and non-zero otherwise (repulsive if the points are too close, attractive if too far).

这是我的Python实现(对不起,我不知道红宝石)。只需导入此,并呼吁统一的(),以获得积分的列表。

This is my Python implementation (sorry, I don´t know ruby). Just import this and call uniform() to get a list of points.

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

这篇关于在边界值内表面分发点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆