Hello,
I am trying to sort a randomly ordered list of 3d grids of points. Assume a list of 7x7x7 = 343 points that need to be ordered in the manner shown in the below image.
How can I accomplish this?
Hello,
I am trying to sort a randomly ordered list of 3d grids of points. Assume a list of 7x7x7 = 343 points that need to be ordered in the manner shown in the below image.
How can I accomplish this?
Sort first by Y, then by X, last by Z. Consider rounding the coordinates first, otherwise the order might get messed up because of floating point precision.
Rather than sorting after the fact, I recommend you generate them in the desired order - one step instead of two.
In a code block:
List.Flatten(
Point.ByCoordinates(
x<1>,
y<2>,
z<3>
)
);
Is the order number 51 in your picture meant to be 50?
Yeah, it should be 50.
I have hundreds of storage boxes (cuboids with heights, lengths, and widths) in Revit for tagging in this fashion. The coordinates (location) are fixed, I need to just generate a sequence of numbers to tag them.
Oh so in reality it could be in any order, it just need to follow some sort of logic?
The sorting sequence will be the same.
Min Y, Min X, Column Z (ascending)
Min Y, Min X+1, Column Z (ascending)
Min Y, Min X+2, Column Z (ascending)
…
Min Y+1, Min X, Column Z (ascending)
Min Y+1, Min X+1, Column Z (ascending)
Min Y+1, Min X+2, Column Z (ascending)
…
Max X, Max Y, Max Z
List.GroupByKey and List.SortByKey can provide what you’re after, but you may need to concatenate the Y, X and Z values into a string first, or use three pairs of the nodes.
A Python solution
import sys
import clr
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
OUT = sorted(IN[0], key = lambda p : (p.Y, p.X, p.Z))
I take this opportunity to share solutions with data table (dataframe and.Net DataTable, which allows visualizing the data to check the output order)
import sys
import clr
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import numpy as np
import pandas as pd
data = {}
data["Point"] = IN[0]
data["X"] = [x.X for x in IN[0]]
data["Y"] = [x.Y for x in IN[0]]
data["Z"] = [x.Z for x in IN[0]]
df = pd.DataFrame.from_dict(data)
df2 = df.sort_values(['Y', 'X', 'Z'])
OUT = df2["Point"].values
import clr
import sys
import System
#
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS
#import net library
from System import Array
from System.Collections.Generic import List, IList, Dictionary
clr.AddReference('System.Data')
from System.Data import *
clr.AddReference('System.Data.DataSetExtensions')
clr.ImportExtensions(System.Data.DataTableExtensions)
clr.AddReference("System.Core")
clr.ImportExtensions(System.Linq)
dt = DataTable("Points")
dt.Columns.Add('Point', DS.Point)
dt.Columns.Add('X', System.Double)
dt.Columns.Add('Y', System.Double)
dt.Columns.Add('Z', System.Double)
for pt in IN[0]:
dt.Rows.Add(pt, pt.X , pt.Y, pt.Z)
dataView = dt.DefaultView
dataView.Sort = "Y, X, Z"
dt = dataView.ToTable()
OUT = newDataTable.AsEnumerable().Select(lambda s : s["Point"]).ToArray[System.Object]()