/// <summary> /// Join a glulam onto another one. Returns null if join is not possible. /// </summary> /// <param name="glulam"></param> /// <returns></returns> public Glulam Join(Glulam glulam) { Rhino.Geometry.Intersect.CurveIntersections ci; ci = Rhino.Geometry.Intersect.Intersection.CurveCurve(Centreline, glulam.Centreline, Tolerance, OverlapTolerance); if (ci.Count != 1) { return(null); } if (ci[0].IsOverlap) { return(null); } if (Math.Abs(Centreline.TangentAt(ci[0].ParameterA) * glulam.Centreline.TangentAt(ci[0].ParameterB)) < AngleTolerance) { return(null); } Curve[] NewCentreline = Curve.JoinCurves(new Curve[] { Centreline, glulam.Centreline }); if (NewCentreline.Length != 1) { return(null); } GlulamOrientation NewOrientation = Orientation.Duplicate(); NewOrientation.Join(glulam.Orientation); Glulam new_glulam = CreateGlulam(NewCentreline[0], NewOrientation, Data.Duplicate()); new_glulam.Data.Samples = Data.Samples + glulam.Data.Samples; return(new_glulam); }
public StraightGlulam(Curve curve, GlulamOrientation orientation, GlulamData data) : base() { Data = data.Duplicate(); Orientation = orientation; Centreline = curve.DuplicateCurve(); //Centreline.Domain.MakeIncreasing(); }
public Beam(Curve centreline, GlulamOrientation orientation, double width, double height) { Centreline = centreline; Orientation = orientation; Width = width; Height = height; }
public override GlulamOrientation[] Split(IList <double> t) { GlulamOrientation[] new_orientations = new GlulamOrientation[t.Count + 1]; for (int i = 0; i < new_orientations.Length; ++i) { new_orientations[i] = this.Duplicate(); } return(new_orientations); }
public Beam(Curve centreline, Curve section, GlulamOrientation orientation) { Centreline = centreline; Orientation = orientation; Section = section; BoundingBox bb = section.GetBoundingBox(true); Width = bb.Max[0] - bb.Min[0]; Height = bb.Max[1] - bb.Min[1]; }
public override GlulamOrientation Join(GlulamOrientation orientation) { if (orientation is VectorListOrientation) { VectorListOrientation vlo = orientation as VectorListOrientation; VectorParameter[] temp = new VectorParameter[m_guides.Length + vlo.m_guides.Length]; Array.Copy(m_guides, temp, m_guides.Length); Array.Copy(vlo.m_guides, 0, temp, m_guides.Length, vlo.m_guides.Length); Array.Sort(temp, (a, b) => a.Parameter.CompareTo(b.Parameter)); m_guides = temp; } return(this.Duplicate()); }
public Glulam Trim(Interval domain, double overlap) { double l1 = Centreline.GetLength(new Interval(Centreline.Domain.Min, domain.Min)); double l2 = Centreline.GetLength(new Interval(Centreline.Domain.Min, domain.Max)); double t1, t2; if (!Centreline.LengthParameter(l1 - overlap, out t1)) { t1 = domain.Min; } if (!Centreline.LengthParameter(l2 + overlap, out t2)) { t2 = domain.Max; } domain = new Interval( Math.Max(t1, Centreline.Domain.Min), Math.Min(t2, Centreline.Domain.Max)); double length = Centreline.GetLength(domain); if (domain.IsDecreasing || length < overlap || length < Glulam.OverlapTolerance) { return(null); } double percentage = length / Centreline.GetLength(); GlulamData data = Data.Duplicate(); data.Samples = Math.Max(6, (int)(data.Samples * percentage)); Curve trimmed_curve = Centreline.Trim(domain); GlulamOrientation trimmed_orientation = Orientation.Trim(domain); trimmed_orientation.Remap(Centreline, trimmed_curve); Glulam glulam = CreateGlulam(trimmed_curve, trimmed_orientation, data); return(glulam); }
static public Glulam CreateGlulam(Curve curve, GlulamOrientation orientation, GlulamData data) { Glulam glulam; if (curve.IsLinear(Tolerance)) { glulam = new StraightGlulam(curve, orientation, data); } else if (curve.IsPlanar(Tolerance)) { /* * if (data.NumHeight < 2) * { * data.Lamellae.ResizeArray(data.NumWidth, 2); * data.LamHeight /= 2; * } */ glulam = new SingleCurvedGlulam(curve, orientation, data); } else { /* * if (data.NumHeight < 2) * { * data.Lamellae.ResizeArray(data.NumWidth, 2); * data.LamHeight /= 2; * } * * if (data.NumWidth < 2) * { * data.Lamellae.ResizeArray(2, data.NumHeight); * data.LamWidth /= 2; * } */ glulam = new DoubleCurvedGlulam(curve, orientation, data); } return(glulam); }
/// <summary> /// Generate a series of planes on the glulam cross-section. TODO: Re-implement as GlulamOrientation function /// </summary> /// <param name="N">Number of planes to extract.</param> /// <param name="extension">Extension of the centreline curve</param> /// <param name="frames">Output cross-section planes.</param> /// <param name="parameters">Output t-values along centreline curve.</param> /// <param name="interpolation">Type of interpolation to use (default is Linear).</param> public override void GenerateCrossSectionPlanes(int N, out Plane[] frames, out double[] parameters, GlulamData.Interpolation interpolation = GlulamData.Interpolation.LINEAR) { Curve curve = Centreline; double multiplier = RhinoMath.UnitScale(Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem, UnitSystem.Millimeters); //PolylineCurve discrete = curve.ToPolyline(Glulam.Tolerance * 10, Glulam.AngleTolerance, 0.0, 0.0); PolylineCurve discrete = curve.ToPolyline(multiplier * Tolerance, AngleTolerance, multiplier * MininumSegmentLength, curve.GetLength() / MinimumNumSegments); if (discrete.TryGetPolyline(out Polyline discrete2)) { N = discrete2.Count; parameters = new double[N]; for (int i = 0; i < N; ++i) { curve.ClosestPoint(discrete2[i], out parameters[i]); } } else { parameters = curve.DivideByCount(N - 1, true).ToArray(); } //frames = parameters.Select(x => GetPlane(x)).ToArray(); //return; frames = new Plane[parameters.Length]; var vectors = Orientation.GetOrientations(curve, parameters); Plane temp; for (int i = 0; i < parameters.Length; ++i) { temp = Misc.PlaneFromNormalAndYAxis( curve.PointAt(parameters[i]), curve.TangentAt(parameters[i]), vectors[i]); if (temp.IsValid) { frames[i] = temp; } else { throw new Exception(string.Format("Plane is invalid: vector {0} tangent {1}", vectors[i], curve.TangentAt(parameters[i]))); } // TODO: Make back-up orientation direction in this case. } return; N = Math.Max(N, 2); frames = new Plane[N]; Curve CL; double extension = 0; if (Centreline.IsClosed) { CL = Centreline.DuplicateCurve(); } else { CL = Centreline.Extend(CurveEnd.Both, extension, CurveExtensionStyle.Smooth); } parameters = CL.DivideByCount(N - 1, true); GlulamOrientation TempOrientation = Orientation.Duplicate(); TempOrientation.Remap(Centreline, CL); for (int i = 0; i < N; ++i) { Vector3d v = TempOrientation.GetOrientation(CL, parameters[i]); frames[i] = tas.Core.Util.Misc.PlaneFromNormalAndYAxis(CL.PointAt(parameters[i]), CL.TangentAt(parameters[i]), v); } return; /* * double[] ft = new double[Frames.Count]; * double[] fa = new double[Frames.Count]; * * Plane temp; * for (int i = 0; i < Frames.Count; ++i) * { * CL.PerpendicularFrameAt(Frames[i].Item1, out temp); * ft[i] = Frames[i].Item1; * //fa[i] = Math.Acos(temp.YAxis * Frames[i].Item2.YAxis); * fa[i] = Vector3d.VectorAngle(temp.YAxis, Frames[i].Item2.YAxis, Frames[i].Item2); * } * * for (int i = 1; i < fa.Length; ++i) * { * if (fa[i] - fa[i - 1] > Math.PI) * fa[i] -= Constants.Tau; * else if (fa[i] - fa[i - 1] < -Math.PI) * fa[i] += Constants.Tau; * } * * int res; * int max = ft.Length - 1; * double mu; * * double[] angles = new double[N]; * * if (Frames.Count < 3) * interpolation = GlulamData.Interpolation.LINEAR; * * switch (interpolation) * { * case (GlulamData.Interpolation.HERMITE): // Hermite Interpolation * for (int i = 0; i < N; ++i) * { * if (t[i] < ft[0]) * { * angles[i] = fa[0]; * continue; * } * else if (t[i] > ft.Last()) * { * angles[i] = fa.Last(); * continue; * } * * res = Array.BinarySearch(ft, t[i]); * if (res < 0) * { * res = ~res; * res--; * } * * if (res == 0 && res < max - 1) * { * mu = (t[i] - ft[0]) / (ft[1] - ft[0]); * angles[i] = Interpolation.HermiteInterpolate(fa[0], fa[0], fa[1], fa[2], mu, 0, 0); * } * else if (res > 0 && res < max - 1) * { * mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]); * angles[i] = Interpolation.HermiteInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 2], mu, 0, 0); * * } * else if (res > 0 && res < max) * { * mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]); * angles[i] = Interpolation.HermiteInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 1], mu, 0, 0); * } * else if (res == max) * { * angles[i] = fa[res]; * } * * else * continue; * } * break; * * case (GlulamData.Interpolation.CUBIC): // Cubic Interpolation * for (int i = 0; i < N; ++i) * { * if (t[i] <= ft[0]) * { * angles[i] = fa[0]; * continue; * } * else if (t[i] >= ft.Last()) * { * angles[i] = fa.Last(); * continue; * } * * res = Array.BinarySearch(ft, t[i]); * if (res < 0) * { * res = ~res; * res--; * } * * if (res == 0 && res < max - 1) * { * mu = (t[i] - ft[0]) / (ft[1] - ft[0]); * angles[i] = Interpolation.CubicInterpolate(fa[0], fa[0], fa[1], fa[2], mu); * } * else if (res > 0 && res < max - 1) * { * mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]); * angles[i] = Interpolation.CubicInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 2], mu); * * } * else if (res > 0 && res < max) * { * mu = (t[i] - ft[res]) / (ft[res + 1] - ft[res]); * angles[i] = Interpolation.CubicInterpolate(fa[res - 1], fa[res], fa[res + 1], fa[res + 1], mu); * } * else if (res == max) * { * angles[i] = fa[res]; * } * * else * continue; * } * break; * * default: // Default linear interpolation * for (int i = 0; i < N; ++i) * { * res = Array.BinarySearch(ft, t[i]); * if (res < 0) * { * res = ~res; * res--; * } * if (res >= 0 && res < max) * { * if (ft[res + 1] - ft[res] == 0) * mu = 0.5; * else * mu = Math.Min(1.0, Math.Max(0, (t[i] - ft[res]) / (ft[res + 1] - ft[res]))); * angles[i] = Interpolation.Lerp(fa[res], fa[res + 1], mu); * } * else if (res < 0) * angles[i] = fa[0]; * else if (res >= max) * angles[i] = fa[max]; * } * break; * } * * for (int i = 0; i < N; ++i) * { * CL.PerpendicularFrameAt(t[i], out temp); * temp.Transform(Rhino.Geometry.Transform.Rotation(angles[i], temp.ZAxis, temp.Origin)); * planes[i] = temp; * } */ }
public override GlulamOrientation Join(GlulamOrientation orientation) { return(this.Duplicate()); }
public abstract GlulamOrientation Join(GlulamOrientation orientation);
public override GlulamOrientation[] Split(IList <double> t) { GlulamOrientation[] new_orientations = new GlulamOrientation[t.Count + 1]; if (t.Count < 1) { new_orientations[0] = this.Duplicate(); return(new_orientations); } int prev = 0; double prev_param = 0.0; bool flag = false; VectorParameter[] new_guides; int index = 0; foreach (double param in t) { int res = Array.BinarySearch(m_guides, param); if (res < 0) { res = ~res; new_guides = new VectorParameter[res - prev + 1]; Array.Copy(m_guides, prev, new_guides, 0, res - prev); new_guides[new_guides.Length - 1] = new VectorParameter { Parameter = param, Direction = GetOrientation(m_curve, param) }; new_guides[new_guides.Length - 1].CalculateAngularOffset(m_curve); if (prev > 0 || flag) { VectorParameter[] temp = new VectorParameter[new_guides.Length + 1]; temp[0] = new VectorParameter { Parameter = prev_param, Direction = GetOrientation(m_curve, prev_param) }; temp[0].CalculateAngularOffset(m_curve); Array.Copy(new_guides, 0, temp, 1, new_guides.Length); new_guides = temp; } new_orientations[index] = new VectorListOrientation( m_curve, new_guides); prev_param = param; prev = res; flag = true; } else { new_guides = new VectorParameter[res - prev + 1]; Array.Copy(m_guides, prev, new_guides, 0, res - prev + 1); new_orientations[index] = new VectorListOrientation( m_curve, new_guides); prev = res; } index++; } new_guides = new VectorParameter[m_guides.Length - prev + 1]; Array.Copy(m_guides, prev, new_guides, 1, m_guides.Length - prev); new_guides[0] = new VectorParameter { Parameter = t.Last(), Direction = GetOrientation(m_curve, t.Last()) }; new_guides[0].CalculateAngularOffset(m_curve); new_orientations[index] = new VectorListOrientation( m_curve, new_guides); return(new_orientations); }
public override GlulamOrientation Join(GlulamOrientation orientation) { throw new NotImplementedException(); }