public static List <Joint> ClassifyJoints(List <Element> beams, List <JointCondition> jcs) { var types = new List <Joint>(); int c = 0; foreach (var jc in jcs) { Joint type = null; switch (jc.Parts.Count) { // The joint has 2 members case (2): c = jc.Parts[0].Case | (jc.Parts[1].Case << 1); switch (c) { case (0): //type = "EndToEndJoint"; var t0 = (beams[jc.Parts[0].Index] as BeamElement).Beam.Centreline.TangentAt(jc.Parts[0].Parameter); var t1 = (beams[jc.Parts[1].Index] as BeamElement).Beam.Centreline.TangentAt(jc.Parts[1].Parameter); if (t0 * t1 < 0) { t1 = -t1; } if (Math.Abs(t0 * t1) < Math.Cos(SpliceCornerThreshold)) { type = new CornerJoint(beams, jc); } else if (t0 * t1 < Math.Cos(BranchThreshold)) { type = new BranchJoint(beams, jc); } else { type = new SpliceJoint(beams, jc); } break; case (1): //type = "TenonJoint"; type = new TenonJoint(beams, jc.Parts[1], jc.Parts[0]); break; case (2): //type = "TenonJoint"; type = new TenonJoint(beams, jc.Parts[0], jc.Parts[1]); break; case (3): //type = "CrossJoint"; type = new CrossJoint(beams, jc); break; } break; // The joint has 3 members case (3): type = new VBeamJoint(beams, jc); break; // The joint has 4 members case (4): type = new FourWayJoint(beams, jc); break; default: break; } types.Add(type); } return(types); }
public static List <Joint> FindBeamJointConditions(List <Element> elements, double searchDistance, double overlapDistance, double end_threshold = 0.1) { int counter = 0; foreach (var ele in elements) { counter++; } BeamElement be0, be1; var joints = new List <Joint>(); var joined = new List <List <int> >(); // Find joints between more than 2 elements for (int i = 0; i < elements.Count - 1; ++i) { be0 = elements[i] as BeamElement; if (be0 == null) { continue; } var endpoints0 = new Point3d[] { be0.Beam.Centreline.PointAtStart, be0.Beam.Centreline.PointAtEnd }; var matches = new List <int>(); for (int j = i + 1; j < elements.Count; ++j) { be1 = elements[j] as BeamElement; if (be1 == null) { continue; } var endpoints1 = new Point3d[] { be1.Beam.Centreline.PointAtStart, be1.Beam.Centreline.PointAtEnd }; for (int k = 0; k < 2; ++k) { for (int l = 0; l < 2; ++l) { if (endpoints0[k].DistanceTo(endpoints1[l]) < searchDistance) { matches.Add(j); } } } } if (matches.Count == 3) { var vjoint = new VBeamJoint(matches.Select(x => elements[x]).ToArray()); vjoint.Plane = new Plane(endpoints0[0], Vector3d.XAxis, Vector3d.YAxis); joints.Add(vjoint); } else if (matches.Count == 4) { var fjoint = new FourWayJoint(matches.Select(x => elements[x]).ToArray()); fjoint.Plane = new Plane(endpoints0[0], Vector3d.XAxis, Vector3d.YAxis); joints.Add(fjoint); } else { matches = new List <int>(); // temporary... } joined.Add(matches); } for (int i = 0; i < elements.Count - 1; ++i) { be0 = elements[i] as BeamElement; if (be0 == null) { continue; } for (int j = i + 1; j < elements.Count; ++j) { if (joined[i].Contains(j)) { continue; } be1 = elements[j] as BeamElement; if (be1 == null) { continue; } var crv0 = be0.Beam.Centreline; var crv1 = be1.Beam.Centreline; var intersections = Rhino.Geometry.Intersect.Intersection.CurveCurve(crv0, crv1, searchDistance, overlapDistance); foreach (var intersection in intersections) { int type = 0; var tA = intersection.ParameterA; var tB = intersection.ParameterB; if (Math.Abs(tA - crv0.Domain.Min) < end_threshold || Math.Abs(tA - crv0.Domain.Max) < end_threshold) { type += 1; } if (Math.Abs(tB - crv1.Domain.Min) < end_threshold || Math.Abs(tB - crv1.Domain.Max) < end_threshold) { type += 2; } Joint joint; switch (type) { case (0): joint = new CrossJoint(be0, tA, be1, tB); break; case (3): joint = new CrossJoint(be0, tA, be1, tB); break; case (1): joint = new TenonJoint(be0, tA, be1, tB); break; case (2): joint = new TenonJoint(be1, tB, be0, tA); break; default: throw new Exception("Invalid classification"); } joint.Plane = new Plane(intersection.PointA, Vector3d.XAxis, Vector3d.YAxis); joints.Add(joint); } } } return(joints); }