 # Point.pruneduplicates not working the way i want

I want point.pruneduplicates on a big tolerance. 5000mm but it is not working.
i am placing random points on a surface, but i want tohe points to have a minimum distance from eachother.

I am a beginner in Python, trying to find the time to learn more (especially after last years BILTeur)

i only need the random points in a flat surface, i found some code, but how to get this into a dynamo node.

``````    import numpy as np
import matplotlib.pyplot as plt

def generate_points_with_min_distance(n, shape, min_dist):
# compute grid shape based on number of points
width_ratio = shape / shape
num_y = np.int32(np.sqrt(n / width_ratio)) + 1
num_x = np.int32(n / num_y) + 1

# create regularly spaced neurons
x = np.linspace(0., shape-1, num_x, dtype=np.float32)
y = np.linspace(0., shape-1, num_y, dtype=np.float32)
coords = np.stack(np.meshgrid(x, y), -1).reshape(-1,2)

# compute spacing
init_dist = np.min((x-x, y-y))

# perturb points
max_movement = (init_dist - min_dist)/2
noise = np.random.uniform(low=-max_movement,
high=max_movement,
size=(len(coords), 2))
coords += noise

return coords

coords = generate_points_with_min_distance(n=8, shape=(2448,2448), min_dist=256)

# plot
plt.figure(figsize=(10,10))
plt.scatter(coords[:,0], coords[:,1], s=3)
plt.show()
``````

or this code?

``````import numpy as np
import matplotlib.pyplot as plt

# specify params
n = 500
shape = np.array([64, 64])
sensitivity = 0.8 # 0 means no movement, 1 means max distance is init_dist

# compute grid shape based on number of points
width_ratio = shape / shape
num_y = np.int32(np.sqrt(n / width_ratio)) + 1
num_x = np.int32(n / num_y) + 1

# create regularly spaced neurons
x = np.linspace(0., shape-1, num_x, dtype=np.float32)
y = np.linspace(0., shape-1, num_y, dtype=np.float32)
coords = np.stack(np.meshgrid(x, y), -1).reshape(-1,2)

# compute spacing
init_dist = np.min((x-x, y-y))
min_dist = init_dist * (1 - sensitivity)

assert init_dist >= min_dist
print(min_dist)

# perturb points
max_movement = (init_dist - min_dist)/2
noise = np.random.uniform(
low=-max_movement,
high=max_movement,
size=(len(coords), 2))
coords += noise

# plot
plt.figure(figsize=(10*width_ratio,10))
plt.scatter(coords[:,0], coords[:,1], s=3)
plt.show()
``````

These are more than one questions.

1. pruneDuplicates:
I think your tolerance is so high that no points can be delete.

You can put a python code in a python node

3. Dynamo uses ironpython 2.7
You can’t use numpy

i think that Dynamo uses your Revit Project settings for units.
5000 == 5000 meters, use 0.5 / 0.05 instead.

I know we can place it in a node… but what do i change to set as input IN and output OUT

need to adjust the code for that.

Your first line of python won’t work in Dynamo as it uses iron python which is capped at 2.7 so numpy won’t import.

Can you post a sample file so someone can try and reproduce the issue you’re having with the prune duplicates node?

Are you in Dynamo Sandbox, Dynamo Revit, Dynamo for Civil 3D, Dynamo for Formit, Dynamo for Alias, or… also if in anything but sandbox what are your project units in that file?

what i am trying now… based on the max X and Max Y and the minimum distance you have an maximum amount of points… if i random the points on the X axis and i do that times the maximum lines Y… then i should get the random points i need…I think

test.dyn (56.6 KB)

I wrote a script once to place random trees inside a polygon:

Script added, I hope you can understand how I did:

Basically it creates an cross-product of the divided X and Y and corrects it with a random value. To be sure they don’t touch eachother, there is an extra correction distance.

1 Like

i think it is working, but it is running for ever…is that correct (already running 10min) @Anton_Huizinga

I think you have a huge area and a short distance between the points.

Dynamo is not fast, maybe you can optimize the script. But I advice to try it first on a small area Or leave out the inside polygon node, since you position the points on a Surface anyway.

could i get some help with this:

i have this code… but i want it to accept multiple inputs (see math.ceiling)
But i also want it to output the list x times… so get an extra input repeat (this repeat will be a list as well)

So you get.
list 0 (this is the math.ceiling list)
------list 0 (number of times repeat)
-------------0 value
-------------1 value
-------list 1 (number of times repeat)
-------------0 value
-------------1 value
-------------2 value
list 1 (this is the math.ceiling list)
------list 0 (number of times repeat)
-------------0 value
-------------1 value
-------list 1 (number of times repeat)
-------------0 value
-------------1 value
-------------2 value

``````import random

NumberOfPoints = IN
MinimumDistance =IN
MaximumDistance = IN

d = sorted(random.randint(0, MaximumDistance-1) for _ in range(NumberOfPoints))
o = [b - a for a, b in zip( + d[:-1], d)]

outputlist=([i * MinimumDistance + sum(o[:i + 1]) for i in range(NumberOfPoints)])

OUT = outputlist``````