Damon wrote:
I've written a Rhinoscript that given two lines, the script will join them if (a) they share an end point and (b) the angle of the tangent vector at their shared end point is less than a specified value. I'd like to expand this to do it for a large number of curves all at once.
Back up a bit to the bigger picture: people in my (architecture) firm like to design a surface/mass then subdivide the surface into a triangulated grid. Everybody uses different ways of doing this. I've been asked a number of times to take the resulting grid of lines and turn it into a set of triangular surfaces and sweep a profile along each curve/line to build an architectural model of glass/metal panels and steel structure. Sometimes the grid is a bunch of continuous degree-3 curves, sometimes degree-3 curves that go from node-to-node, sometimes straight lines that go from node-to-node, and sometimes polylines in each direction.
In any of these cases, I can create the sweeps for the structural members, that's not a problem.
For panels, it's another story. Given polylines or continous degree-3 curves along each diagonal (or in U and V directions), I have no problem creating panels. However, if they've split the curves/lines at the node intersections and haven't sorted them previously by layer for each direction, it's a tedious process. (I'd like to encourage/teach people how to create grids in a more useful way, but partly for practical reasons and partly for self-educational reasons, I think this is an interesting problem to solve.)
Any suggestions for working through a whole list of curves would be greatly appreciated. Here's what I have so far that works for the simple case of testing two curves:
Call JoinCurvesToPath() Sub JoinCurvesToPath() Dim arrCrv : arrCrv = Rhino.GetObjects("Select two curves to join into a polycurve", 4) If IsNull(arrCrv) Then Exit Sub Call Rhino.EnableRedraw(False) Dim crvA : crvA = arrCrv(0) Dim crvB : crvB = arrCrv(1) Dim arrParams Dim angle : angle = 15 'Find joining ends arrParams = JoiningEnds(crvA, crvB) If Not (IsNull(arrParams)) Then 'Join curves if angle is met. Call JoinCurves(crvA, crvB, arrParams, angle) End If Call Rhino.EnableRedraw(True) End Sub Function JoiningEnds(crvA, crvB) Call Rhino.Print("In JoiningEnds function") Dim startA, endA, startB, endB Dim paramA, paramB startA = Rhino.CurveStartPoint(crvA) endA = Rhino.CurveEndPoint(crvA) startB = Rhino.CurveStartPoint(crvB) endB = Rhino.CurveEndPoint(crvB) If (Rhino.Distance(startA, startB) < 0.1) Then Call Rhino.Print("starts") paramA = Rhino.CurveClosestPoint(crvA, startA) paramB = Rhino.CurveClosestPoint(crvB, startB) JoiningEnds = Array(paramA, paramB) ElseIf (Rhino.Distance(startA, endB) < 0.1) Then Call Rhino.Print("start, end") paramA = Rhino.CurveClosestPoint(crvA, startA) paramB = Rhino.CurveClosestPoint(crvB, endB) JoiningEnds = Array(paramA, paramB) ElseIf (Rhino.Distance(endA, endB) < 0.1) Then Call Rhino.Print("ends") paramA = Rhino.CurveClosestPoint(crvA, endA) paramB = Rhino.CurveClosestPoint(crvB, endB) JoiningEnds = Array(paramA, paramB) ElseIf (Rhino.Distance(endA, startB) < 0.1) Then Call Rhino.Print("end, start") paramA = Rhino.CurveClosestPoint(crvA, endA) paramB = Rhino.CurveClosestPoint(crvB, startB) JoiningEnds = Array(paramA, paramB) End If End Function Function JoinCurves(crvA, crvB, arrParams, minAngle) Dim vecA, vecB Dim joined vecA = Rhino.CurveTangent(crvA, arrParams(0)) If IsNull(vecA) Then Call Rhino.Print("CurveTangent at A failed") Exit Function End If vecB = Rhino.CurveTangent(crvB, arrParams(1)) If IsNull(vecB) Then Call Rhino.Print("CurveTangent at B failed") Exit Function End If Dim angle: angle = Rhino.VectorAngle(vecA, vecB) Call Rhino.Print("Angle = " & angle) If (angle < minAngle) Then joined = Rhino.JoinCurves(Array(crvA, crvB)) Call Rhino.Print("joined has " & Ubound(joined) + 1 & "objects") JoinCurves = joined(0) Call Rhino.DeleteObjects(Array(crvA, crvB)) Else JoinCurves = Null End If End Function
Posts: 1
Participants: 1