How to get group of wall at 45°

Hi all,

I have three wall at 45° but i can’t understand how to group wall at 45°. it’s make it 2 group of wall as per below snip.

Hi Robert could something help…

1 Like

No, @sovitek

my problem is three walls are angle same and get 2 group of wall.

Hi @robert12546358 ,

Could you share a screenshot of your Dynamo script after implementing the suggestion of @sovitek ?

What is the problem? You only have one group, together with one corresponding key.

1 Like

Alright…why do you use list level 2…dont think i understand the problem and what you try then :wink:

i have required 3 group of wall as coordinate X & Y with difference angle as shown below snip.

I see, this is not grouping by angle though.

If you want to group them by their continuous line you could approach this “mathematical”.

First start by grouping them by their rotation value. Then group them by their intersection point with the Y-axis, you can do this by creating a plane in Dynamo along the X-axis, then project the wall’s vector/ line onto that Plane, such that you find the intersection of the plane and the wall line (if it was extended).

Then simply only get the Y-value of that intersection point and then group your walls again by that.

PS: This is how I would do this, maybe there are other, better ways.

2 Likes

I think it’d be best to try the following here.

  1. Filter out any non-linear walls. They don’t apply here anyway.
  2. Find the location lines, and pull the bounding rectangle of this collection by taking the bounding box of the planar curves, converting to a cuboid, explode that twice (to get a surface, and then curves) and make a PolyCurve from the resulting joined curves.
  3. Get the maximum value of the bounding surface by pulling the distance between the min and max point of the bounding box from step 2.
  4. Extend all the wall curve’s start point by the distance from step 3.
  5. Intersect the extended curves from step 4 with the rectangle from step 2, returning two points. Convert those points to parameters via a Curve.PointAtParameter node and sort the pair from smallest to largest. You now have a unique “start/end” parameter value for each direction which walls were drawn.
  6. Round each number pair to a desired degree of accuracy, convert them to strings, and join the two with a separating value (say a ,). This is now a single item which can be used as a key in the context of the larger design.
  7. Take the list of linear walls from step one as a list, group them by the key parameters I from step six. The resulting groups should be all elements which are co-linear to the degree of rounding you used.

Give it a shot and if you get stuck I’ll take a stab at it later this week.

2 Likes

good evening,
there may be the possibility of using Thales and similar triangles with an inclined line large created from one of the low points,

I will try to dig on this side after tomorrow
Cordially
christian.stan

Took a stab at my method; Pretty good results as it will group 2000 curves by alignment in about 4.5 seconds. Your mileage may vary of course.

The DesignScript definition I used is as follows:


def groupAligned (crvList: Curve[])
{
	bb = BoundingBox.ByGeometry(crvList);
	dist = Geometry.DistanceTo(bb.MinPoint,bb.MaxPoint);
	extended = crvList.ExtendStart(dist).ExtendEnd(dist);
	boundRec =
		PolyCurve.ByJoinedCurves(
			bb.ToCuboid().Explode().PerimeterCurves()
		)[0];
	intersects =
		DSCore.List.Transpose(
			DSCore.List.Sort(
				Curve.ParameterAtPoint(
					boundRec,
					Geometry.Intersect(boundRec,extended)
				)@L2<1>
			)
		);
	uvVals = UV.ByCoordinates(intersects[0],intersects[1]);
	groups = DSCore.List.GroupByKey(crvList,uvVals);
	return = groups["groups"];
};

3 Likes

hello, another possibility
create bounding boxes around elements
create lines joining the centroids of the 1st with respect to the other centroids if all these lines are tilted by 45°,

it means that these objects are aligned (remove them from the list then, start again with the non-removed objects until the end of the list)

unfortunately I am not competent enough to format it ,
after I am not sure of the greediness in calculation time

Cordially
christian.stan

Hello,
I tried another possibility (Intersection of the midplanes of the walls) , I’m on the right track but I don’t know the node (List.GroupBykey to have a correct end)

occasionally if you could enlighten me (depending on your schedule), that would be nice of you. Thanks in advance.
essai verif colinearite.dyn (31.8 KB)

A curious thing (the intersection of 2 planes returns Pi (hidden)

cordially
christian.stan

Can you quickly outline the logic in steps as I did above?

I’ll look into this later this week if so.

1 Like

Thanks,
To follow up on the message
1-Selection of walls with the same inclination
2-Recovery of the support lines of the walls
3-Creation of vertical planes passing through the median axis of the walls
4- Intersection of these same planes between them (vector product) with the same entrants
5-Consequence:
Surface exists (collinear), empty (not collinear)
6- I empty-handed to clip at the end (I’m a beginner)

I did a test with 7 walls as a screen
Capture d’écran 2022-05-26 184250

Cordially
christian.stan

An alternative using vectors comparison (cross product)

import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB


def group_byAlignement(lstelems, i = 0):
	"""
	recursive function to group linear walls using vector comparison
	"""
	if len(lstelems) > 0 and i < 2000:
		group = [lstelems.pop(0)]
		baseVector = group[0].Location.Curve.Direction
		basePt = group[0].Location.Curve.GetEndPoint(0)
		idxToPop = []
		for idx, elem in enumerate(lstelems):
			vectB = elem.Location.Curve.Direction
			ptB = elem.Location.Curve.GetEndPoint(0)
			vect_between_walls = DB.Line.CreateBound(basePt, ptB).Direction
			if round(baseVector.CrossProduct(vectB).GetLength(), 3) == round(vectB.CrossProduct(vect_between_walls).GetLength(), 3) == 0.0:
				group.append(elem)
				idxToPop.append(idx)
			
		other = [e for idxa, e in enumerate(lstelems) if idxa not in idxToPop]
		return [group] + group_byAlignement(other, i + 1)
	else: return []
		

toList = lambda x : list(x) if hasattr(x, '__iter__') else [x]
lstelems = toList(UnwrapElement(IN[0]))

OUT = group_byAlignement(lstelems)
5 Likes

Thanks @c.poupin :grinning: :grinning: :grinning: :+1: :+1: :+1:

2 Likes