# Oops...

This website is made for modern browsers. You are seeing this, because your browser is missing a feature or two. Please install the latest update or switch to a modern browser. See you soon.

# Remove duplicate curves

When working with curves in Grasshopper, it’s sometimes useful to remove duplicate curves. The more curves are processed in an algorithm, the longer does the computation take for each step. Also, duplicate curves might lead to mistakes in quantifycations and other calculations.

Kangaroo2 has a utility component removeDuplicateLines

removeDuplicateLines (dupLn)
Kangaroo2  >  Utility  >  removeDuplicateLines
Removes similar lines from a list.
Inputs
lines (L)list of lines to clean
tolerance (t)lines with start/endpoints closer than this distance will be combined
Outputs
unique lines (Q)list of unique lines
that will solve the said for lines and so does Karamba with Remove Duplicate Lines (Karamba3D)
Remove Duplicate Lines (Karamba3D) (RDLines)
Karamba3D  >  8.Utilities  >  Remove Duplicate Lines (Karamba3D)
Eliminates identical lines from the given set of lines.
Inputs
Line (L)Input Lines
Limit distance (LDist)Limit Distance for coincident points
Outputs
OutLine (L)Output Lines
Info (Info)Information regarding the removal of duplicate lines
Indexes (I)Indexes of removed lines
. But, both components only allow lines to be processed. There might be a plugin that will solve this case for curves, but in this how-to guide we introduce two methods that work with vanilla Grasshopper. And yes, both methods will also work with lines.

### Remove duplicate curves (simple comparison)

Before we can remove anything, we have to identify the properties that duplicate curves share and which can be used to identify the duplicates. Often, it’s sufficient to check for identical midpoints. For example in those cases, when the duplicate curves were created by the edges of two adjacent surfaces.

The first step is to bundle all curves in a list and to flatten them if needed. Then we use Point On Curve

Point On Curve (CurvePoint)
Curve  >  Analysis  >  Point On Curve
Evaluates a curve at a specific location
to find the midpoints.
We use the midpoints, because the endpoints might be flipped.
We use the midpoints, because the endpoints might be flipped. The component Cull Duplicates
Cull Duplicates (CullPt)
Vector  >  Point  >  Cull Duplicates
Cull points that are coincident within tolerance
Inputs
Points (P)Points to operate on
Tolerance (T)Proximity tolerance distance
Outputs
Points (P)Culled points
Indices (I)Index map of culled points
Valence (V)Number of input points represented by this output point
can be used to remove duplicate midpoints and thus, the corresponding curves can be identified. To get the indices we need from output I, we have to right-click the component and select Leave One. We can then attach a List Item
List Item (Item)
Sets  >  List  >  List Item
Retrieve a specific item from a list.
Inputs
List (L)Base list
Index (i)Item index
Wrap (W)Wrap index to list bounds
Outputs
Item (i)Item at {i'}
component to get all unique curves.

### Remove duplicate curves (advanced comparison)

There can be cases in which deviant curves meet at their midpoints, for example in an X. With the previous method, those curves would be falsely identified as duplicates. If we suspect that this case might occur, we have to think of a more advanced method for comparison; one that takes various criteria into account. Then, if all criteria match, we can assume that the curves are congruent.

To proceed with this idea, we will concatenate the curves' attributes into a string, which we use a simplified hash value. Then we compare these hashes to identify duplicate curves. In this example, we will use the endpoints as additional attributes.

After bundling all curves, we will use Point On Curve

Point On Curve (CurvePoint)
Curve  >  Analysis  >  Point On Curve
Evaluates a curve at a specific location
and also End Points
End Points (End)
Curve  >  Analysis  >  End Points
Extract the end points of a curve.
Inputs
Curve (C)Curve to evaluate
Outputs
Start (S)Curve start point
End (E)Curve end point
. Then, we Merge
Merge (Merge)
Sets  >  Tree  >  Merge
Merge a bunch of data streams
Inputs
Data 1 (D1)Data stream 1
Data 2 (D2)Data stream 2
Outputs
Result (R)Result of merge
all points and graft the inputs to get a list of points for each curve. We have to use Sort Points
Sort Points (Sort Pt)
Vector  >  Point  >  Sort Points
Sort points by Euclidean coordinates (first x, then y, then z)
Inputs
Points (P)Points to sort
Outputs
Points (P)Sorted points
Indices (I)Point index map
to equalize the drawing direction and Text Join
Text Join (Join)
Sets  >  Text  >  Text Join
Join a collection of text fragments into one
Inputs
Text (T)Text fragments to join.
Join (J)Fragment separator.
Outputs
Result (R)Resulting text
will transform the points into a hash value.

Next, we flatten the hashes and use Create Set

Create Set (CSet)
Sets  >  Sets  >  Create Set
Creates the valid set from a list of items (a valid set only contains distinct elements).
Inputs
List (L)List of data.
Outputs
Set (S)A set of all the distincts values in L
Map (M)An index map from original indices to set indices
and Member Index
Member Index (MIndex)
Sets  >  Sets  >  Member Index
Find the occurences of a specific member in a set.
Inputs
Set (S)Set to operate on.
Member (M)Member to search for.
Outputs
Index (I)Indices of member.
Count (N)Number of occurences of the member.
to create branches for curves with the same hash value. Each branch contains the references (indices) for the respective curves. Because we only need one curve each, we will use List Item
List Item (Item)
Sets  >  List  >  List Item
Retrieve a specific item from a list.
Inputs
List (L)Base list
Index (i)Item index
Wrap (W)Wrap index to list bounds
Outputs
Item (i)Item at {i'}
to get the first reference index from each list. Then, we flatten this list and connect it to another List Item
List Item (Item)
Sets  >  List  >  List Item
Retrieve a specific item from a list.
Inputs
List (L)Base list
Index (i)Item index
Wrap (W)Wrap index to list bounds
Outputs
Item (i)Item at {i'}
, together with the initial curve bundle. We remain with the desired curves.

This advanced comparison can be extended to check for more attributes that make a curve unique, like tangents at the endpoints. Also, this principle can be applied to other geometries; we just have to think about the properties that congruent objects share. To regard tolerances, we could round the properties and adjust their decimal places before we translate them into a string.

This page is open source. Edit it on GitHub or see how you can contribute.