Populate Geometry (global control)

Hi! I came across a situation where I’d love your input.
I large-ish have a set of curves for which I would like to populate the interiors with points. The thing is I want to be able to set the total number of points and distribute them based on the size of the area of each curve (I am after a fairly even distribution from a visual point of view).
I’ve prepared a simplified example below with what the standard component does and what I’m after (I specifically chose a value that exemplifies my logic, but also breaks down due to roundoffs I suspect).

popgeo_q.gh (18.2 KB)

Looks to me like you are very, very close. This cyan group corrects for round-off error.

popgeo_2021_Jul21a.gh (22.3 KB)

Have you tried playing with ‘Seed’ values? Integers in the range 0 to 300 works for me.

Come to think of it, you might want a unique ‘Seed’ value for each letter/curve?

1 Like

This demonstrates the difference.

When the ‘Seed’ slider is connected directly to the PopGeo ‘S’ input, both copies of each letter have the same point distribution. But when Random is connected to the PopGeo ‘S’ input, duplicate letters have different point distributions because each has a unique seed.

popgeo_2021_Jul21b.gh (28.0 KB)

The forum software apparently shrinks large animated .gif files? Trying again…
Foiled again. :frowning: Maybe direct links to these images?

Clicking that works to see the image full size. This is not nice behavior by the forum software.


Now click this to see full size? :man_facepalming:


If you did want a more even distribution than you get directly from the populate component, here’s a way to relax it:

text_pts.gh (31.8 KB)


Amazing! I can follow the logic up through the Sqrt component, then wonder why that is multiplied by 1.5? Plugging in a ‘1 to 2’ slider instead of 1.5 (why not), I can see the effect of smaller and larger values but why is that number labeled ‘range’ on the C# input?

Does the C# code have to be modified for each use or is it general purpose? What is it doing?

Thanks. Very cool.

P.S. For what it’s worth, which isn’t much, here are Daniel’s letters and symbols and 2000 points retrofitted to the earlier code. Not cool by comparison.

popgeo_2021_Jul21c.gh (41.2 KB)


Thanks :slight_smile:

It’s a goal for repulsion with a strength that’s a power of inverse distance - so strong when the points are close, falling off as they are further apart.

You could also use elastic spheres (as in the SphereCollide goal) to push things apart, but there strength is a linear function of distance with a hard cutoff, and I find that the falloff from the power law repulsion often results in a nicer distribution.

The problem with inverse distance functions though is that you end up with all points affecting all the other points, so a lot to calculate. Above some distance though, the strength gets pretty negligible if you’re using something like an inverse cube strength, so you can just ignore it with little change in the result. Then you are dealing with only local interactions and can use spatial sorting to give a big speedup.
The goal also adjusts it so that this cutoff isn’t a hard step, but blends down to zero within the given range.
There was nothing special about the value of 1.5 I chose in this example - it was just what worked to give a good distribution here. A value for range that is enough so that each point interacts with its neighbours and their neighbours is usually enough to give a nice result, and going higher just slows things down without much benefit.

The C# should work without modification anywhere you have points you want to push apart.
I’ll probably make it a standard included Kangaroo goal component soon, I was just refining it a bit.
I’ve also posted some other definitions using this goal or slight variations on it here:


Hi @Joseph_Oster & @DanielPiker

Thank you both for taking the time and providing solutions! I left the OP last night in frustration just before calling it a day so this would explain my late reply.
I promise I’ll get back with the final result for all of this :wink: