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[1] / shape[0]
    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]-1, num_x, dtype=np.float32)
    y = np.linspace(0., shape[0]-1, num_y, dtype=np.float32)
    coords = np.stack(np.meshgrid(x, y), -1).reshape(-1,2)

    # compute spacing
    init_dist = np.min((x[1]-x[0], y[1]-y[0]))

    # 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[1] / shape[0]
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]-1, num_x, dtype=np.float32)
y = np.linspace(0., shape[0]-1, num_y, dtype=np.float32)
coords = np.stack(np.meshgrid(x, y), -1).reshape(-1,2)

# compute spacing
init_dist = np.min((x[1]-x[0], y[1]-y[0]))  
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()

please help

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.

tried a lot of values… no result.

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?

test.dyn (66.7 KB)


draw a spline run the script

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:

https://www.linkedin.com/posts/antonhuizinga_vraag-is-het-mogelijk-om-met-dynamo-voor-activity-6580816211079163904-mXiK

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

bonus 02 - Random bomen - resultaat.dyn (33.8 KB)

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 :slight_smile:

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[0]
MinimumDistance =IN[1]
MaximumDistance = IN[2]


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

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

OUT = outputlist

Just to add to this in case anyone is still looking for why the component doesn’t seem to work at first: The prune duplicate component doesn’t use your inputted tolerance unless you right-click tolerance and uncheck “Use Default Value”.