Points snap to grid with no two at the same location

Hi Grasshopper hive mind,

I’m trying to space annotation bubbles on a drawing without them overlapping.

I snap them to the nearest point on a diagrid, except two may share the same point therefore end up on top of each other.

I could code the recursion, or use kangaroo repulsion, but wondered if i was missing a simple trick.

logic is to have each bubble snap to its nearest point, unless that point is already taken (by a bubble closer to that point), in which case it goes to the next closest point. Repeat until all bubbles find a home.

A first pass in the script below (uses lunchbox to make diagrid).

takes input points
finds clusters of points
constructs local diagrid over each cluster
for each input point which makes the cluster, find the proximity to each node of the diagrid

snap to closest point without duplicates.gh (20.2 KB)

Many thanks for your CPU cycles as always.

R

Hi All,

I hacked together a basic lexical solution to this. It only uses the first closest point to each node, and at edge cases this means some points don’t find a node to snap to. It does have an error message when this happens, increasing the number of nodes to snap to will fix. It also synchronously sorts any generic data and outputs an index map of the transformed points. Should take data trees or a simple lists as input.

A scripted solution would solve this but, alas, time.

Essentially this ought to be a component, called something like Closest Point Exclusive.

I can see many uses for this beyond the dull one above. 'Must have been solved before; doubt I’m the first to need it. 'Hope this helps anyone who needs a quick fix like i did. I welcome anyone improving on on it.

R

snap to closest point without duplicates_V001.gh (49.6 KB)

Get rather the fastest C# take on that (very basic coding skills required).

RndPts_OrthoOrNot_EnteryLevel_V1.gh (28.3 KB)

pETER!

I’m honoured. I’ve never even ridden a Ducati. 'A long time appreciater of your work

What a typically elegant and self - contained approach! thank you for your time and brainhorsepower, i see how it works. nice.

My hunch that to solve the issue mathematically “properly” (way past what I need to automagically mark-up a foundation detail) it requires a recursive approach (like yours has) with the addition of a fitness value.

Consider a situation where a bunch of points looking for a home are clustered around a single node (the last chair in a game of musical chairs), elsewhere nodes are available, but the closest ones to this cluster also have points near to them.

So a ripple out from this cluster is needed… pushing all the points out until those in the cluster find the nearest homes and those around the surrounding nodes are gently shooed out to their next nearest points as their spots are filled.

This was what kangaroo could easily do, but there’s clearly a scripted solution.

Psuedo script (stuck in foundations of a house right now, but will give it a go at some point, in python or sometimes VB sorry I know C# is your metalhorse of choice)

1 Add cumulative total distance from each homeless point to every node in the target grid -
Easy with components (closest points to the length of the target grid, mass addition of the distances)
(sluggish i know) - this gives a ‘fitness value’ for each homeless point- the smaller the number the more embedded in the nodes the point is. slider in the file below scrubs through the points ordered in this way

snap to closest point without duplicates_V003.gh (54.3 KB)

2 The fittest point is given to its closest node in the target grid. This node is removed from the target grid

3 The next fittest point takes its closest node, that node is eliminated, repeat until all points are home

(ideally a component to do this would have an input for the homeless points, one for the target grid, with either or both able to take data trees, and an index output for synchronous sorting of data alongside the transformed points).

Watch this space, as you say… Improving!

keep fighting the good fight. life doesn’t suck all the time… though it is all the time, all we have. And what an All.

R

Better imagine a bunch of Ducatis(*) looking for takers. Post MotoGP (forza Ducati) I’ll rovide some stuff on that matter. Easy: no need for weird algos/things: just use some Point3dList based proximity while monitoring the visited grid positions ( via a classic bool [ , ] the size of grid rows/columns).

(*) if we exclude that super ugly 999 (designers are born, not made).

BTW: VB is dead. Avoid spending time on that thing.

That’s rather serious: what bike you ride? (hope not a H/D).

As I said that’s elementary (and by no means you need Kangaroo or some other weird algorithm).

RndPts_OrthoOrNot_EnteryLevel_V1A.gh (140.8 KB)

You can: either use your points or let the 2nd C# do a rnd demo.
You can: use a 3d grid (1st C# - spot the getProb var: you can control the vacancy) or not.
You can: have the points as they are or get the “ortho” ones.

Obviously all the resulting “ortho” points are unique.

That said … Ducati won the Jerez MotoGP (1,2,3,4,5 - what else?) plus the Marc VS Pecco dogfight - to the wire - was straight from the good old days. Jap bikes are so far back that Dorna/LM allows them to do development during the season (what a humiliation for Honda and Yamaha).

Moral: Ducati Uber Alles