Hi Japhy,
So I got bunch of PolyCurves / PolyLineCurves that I get from Revit. I want to use this as basis for the geometry I want to build, but first I want to clean the data so I can reduce potential errors down the road. So here is an example of my original curve: outer_boundaries: [<Rhino.Geometry.PolyCurve object at 0x00000261C7BB7500>]. What I want is to take this curve and both round coordinates and snap angles of the polycurve, so the result is a polycurve where all angles close to 90 degrees but not exactly 90 degrees have been corrected so they are indeed 90 degrees. In addition I want to round all points to reduce floating point errors. So I have extracted all vertices and rounded to 3 decimal points, thinking that rounding first can reduce noise before correcting the angles.
At vertex 2: angle ≈ 89.75°
At vertex 3: angle ≈ 89.68°
At vertex 4: angle ≈ 90.32°
So now I want to correct the angles that are slightly off. Guessing a python node is best suited for the task, but any approach is welcome. The loops should all be planar, but the solution still needs to work in a 3d space independent of the coordinate axes.
Below is the same polycurve as above where all vertices has been extracted and rounded [(x,y,z),(x,y,z)…]
outer_boundaries_vertices_rounded_decimal: [[(Decimal(‘10001.932’), Decimal(‘1358.406’), Decimal(‘3000.000’)), (Decimal(‘10022.447’), Decimal(‘-3266.594’), Decimal(‘3000.000’)), (Decimal(‘13027.135’), Decimal(‘-3266.594’), Decimal(‘3000.000’)), (Decimal(‘13061.362’), Decimal(‘2798.406’), Decimal(‘3000.000’)), (Decimal(‘10061.932’), Decimal(‘2798.406’), Decimal(‘3000.000’)), (Decimal(‘10061.932’), Decimal(‘2882.406’), Decimal(‘3000.000’)), (Decimal(‘1061.932’), Decimal(‘2882.406’), Decimal(‘3000.000’)), (Decimal(‘1061.932’), Decimal(‘1358.406’), Decimal(‘3000.000’)), (Decimal(‘10001.932’), Decimal(‘1358.406’), Decimal(‘3000.000’))]]
Hope that gave a little more context, just want a general approach to validate any polycurve obtained from revit to reduce potential errors down the road.
Was thinking something like this:
def enforce_perpendicularity(vertices, tol_deg=1.0):
"""
Function snaps angles that are close to 90 degrees, but not exactly 90 degrees and within tol_deg of 90 degrees. Returns snapped_vertices. If no angles are changed, return same vertices as given as input
"""
return snapped_vertices