public override bool InKLimitsComponent(out bool width, out bool height) { width = height = false; double[] t = Centreline.DivideByCount(CurvatureSamples, false); double max_kw = 0.0, max_kh = 0.0; Plane temp; Vector3d k; for (int i = 0; i < t.Length; ++i) { temp = GetPlane(t[i]); k = Centreline.CurvatureAt(t[i]); max_kw = Math.Max(max_kw, Math.Abs(k * temp.XAxis)); max_kh = Math.Max(max_kh, Math.Abs(k * temp.YAxis)); } double rw = (1 / max_kw) / RadiusMultiplier; double rh = (1 / max_kh) / RadiusMultiplier; if (rw - Data.LamWidth > -RadiusTolerance || double.IsInfinity(1 / max_kw)) { width = true; } if (rh - Data.LamHeight > -RadiusTolerance || double.IsInfinity(1 / max_kh)) { height = true; } return(width && height); }
public Curve CreateOffsetCurve(double x, double y, int samples = 100, bool rebuild = false, int rebuild_pts = 20) { List <Point3d> pts = new List <Point3d>(); double[] t = Centreline.DivideByCount(samples, true); for (int i = 0; i < t.Length; ++i) { Plane p = GetPlane(t[i]); pts.Add(p.Origin + p.XAxis * x + p.YAxis * y); } Curve new_curve = Curve.CreateInterpolatedCurve(pts, 3, CurveKnotStyle.Uniform, Centreline.TangentAtStart, Centreline.TangentAtEnd); double len = new_curve.GetLength(); new_curve.Domain = new Interval(0.0, len); if (rebuild) { new_curve = new_curve.Rebuild(rebuild_pts, new_curve.Degree, true); } return(new_curve); }
public override void CalculateLamellaSizes(double width, double height) { Plane cPlane; Centreline.TryGetPlane(out cPlane); var normal = cPlane.ZAxis; var tt = Centreline.DivideByCount(Data.Samples, true); double k = 0.0; Vector3d kVec; for (int i = 0; i < tt.Length; ++i) { kVec = Centreline.CurvatureAt(tt[i]); k = Math.Max(k, kVec.Length); } double lh = Math.Floor((1 / Math.Abs(k)) * Glulam.RadiusMultiplier); Data.LamWidth = width; int num_height = (int)Math.Ceiling(height / lh); Data.LamHeight = height / Data.LamHeight; if (num_height < 2) { num_height = 2; Data.LamHeight /= 2; } Data.Lamellae.ResizeArray(Data.NumWidth, num_height); }
/// <summary> /// Checks the glulam to see if its lamella sizes are appropriate for its curvature. /// </summary> /// <param name="param">Parameter with maximum curvature.</param> /// <returns>True if glulam is within curvature limits.</returns> public bool InKLimits(out double param) { double[] t = Centreline.DivideByCount(CurvatureSamples, false); double max_k = 0.0; int index = 0; double temp; for (int i = 0; i < t.Length; ++i) { temp = Centreline.CurvatureAt(t[i]).Length; if (temp > max_k) { max_k = temp; index = i; } } param = t[index]; double ratio = (1 / max_k) / RadiusMultiplier; if (Math.Abs(ratio - Data.LamHeight) > RadiusTolerance || Math.Abs(ratio - Data.LamWidth) > RadiusTolerance) { return(false); } return(true); }
public List <Point3d> DiscretizeCentreline(bool adaptive = true) { if (adaptive) { var pCurve = Centreline.ToPolyline(Glulam.Tolerance, Glulam.AngleTolerance, 0.0, 0.0); return(pCurve.ToPolyline().ToList()); } var tt = Centreline.DivideByCount(Data.Samples, true); return(tt.Select(x => Centreline.PointAt(x)).ToList()); }
public override void CalculateLamellaSizes(double width, double height) { var tt = Centreline.DivideByCount(Data.Samples, true); Plane kPlane; Vector3d kVec; double maxKX = 0.0, maxKY = 0.0; double dotKX, dotKY; for (int i = 0; i < tt.Length; ++i) { kPlane = GetPlane(tt[i]); kVec = Centreline.CurvatureAt(tt[i]); dotKX = kVec * kPlane.XAxis; dotKY = kVec * kPlane.YAxis; maxKX = Math.Max(dotKX, maxKX); maxKY = Math.Max(dotKY, maxKY); } double lh = Math.Floor((1 / Math.Abs(maxKY)) * Glulam.RadiusMultiplier); double lw = Math.Floor((1 / Math.Abs(maxKX)) * Glulam.RadiusMultiplier); int num_height = (int)Math.Ceiling(height / lh); Data.LamHeight = height / num_height; int num_width = (int)Math.Ceiling(width / lw); Data.LamWidth = width / num_width; if (Data.NumHeight < 2) { num_height = 2; Data.LamHeight /= 2; } if (Data.NumWidth < 2) { num_width = 2; Data.LamWidth /= 2; } Data.Lamellae.ResizeArray(num_width, num_height); }
public override Curve CreateOffsetCurve(double x, double y, bool offset_start, bool offset_end, bool rebuild = false, int rebuild_pts = 20) { if (!offset_start && !offset_end) { return(Centreline.DuplicateCurve()); } if (offset_start && offset_end) { return(CreateOffsetCurve(x, y, rebuild, rebuild_pts)); } List <Point3d> pts = new List <Point3d>(); double[] t = Centreline.DivideByCount(this.Data.Samples, true); double tmin = offset_start ? t.First() : t.Last(); double tmax = offset_end ? t.Last() : t.First(); for (int i = 0; i < t.Length; ++i) { Plane p = GetPlane(t[i]); double l = Ease.QuadOut(Interpolation.Unlerp(tmin, tmax, t[i])); pts.Add(p.Origin + p.XAxis * l * x + p.YAxis * l * y); } Curve new_curve = Curve.CreateInterpolatedCurve(pts, 3, CurveKnotStyle.Uniform, Centreline.TangentAtStart, Centreline.TangentAtEnd); if (new_curve == null) { throw new Exception(this.ToString() + "::CreateOffsetCurve:: Failed to create interpolated curve!"); } double len = new_curve.GetLength(); new_curve.Domain = new Interval(0.0, len); if (rebuild) { new_curve = new_curve.Rebuild(rebuild_pts, new_curve.Degree, true); } return(new_curve); }
public override double GetMaxCurvature(ref double width, ref double height) { double[] t = Centreline.DivideByCount(CurvatureSamples, false); double max_kw = 0.0, max_kh = 0.0, max_k = 0.0; Plane temp; Vector3d k; for (int i = 0; i < t.Length; ++i) { temp = GetPlane(t[i]); k = Centreline.CurvatureAt(t[i]); max_kw = Math.Max(max_kw, Math.Abs(k * temp.XAxis)); max_kh = Math.Max(max_kh, Math.Abs(k * temp.YAxis)); max_k = Math.Max(max_k, k.Length); } width = max_kw; height = max_kh; return(max_k); }
public Point3d[] ToBeamSpace(IList <Point3d> pts, bool approximate = false, int num_samples = 100) { Point3d[] m_output_pts = new Point3d[pts.Count]; Plane m_plane; Point3d m_temp; double t; if (approximate) { double mu; var tt = Centreline.DivideByCount(num_samples, true); var lengths = tt.Select(x => Centreline.GetLength(new Interval(Centreline.Domain.Min, x))).ToArray(); //for (int i = 0; i < pts.Count; ++i) Parallel.For(0, pts.Count, i => { Centreline.ClosestPoint(pts[i], out t); m_plane = GetPlane(t); m_plane.RemapToPlaneSpace(pts[i], out m_temp); var res = Array.BinarySearch(tt, t); if (res < 0) { res = ~res; res--; } if (res >= 0 && res < tt.Length - 1) { mu = (t - tt[res]) / (tt[res + 1] - tt[res]); m_temp.Z = Interpolation.Lerp(lengths[res], lengths[res + 1], mu); } else if (res < 0) { m_temp.Z = lengths.First(); } else if (res >= (tt.Length - 1)) { m_temp.Z = lengths.Last(); } m_output_pts[i] = m_temp; } ); } else { //for (int i = 0; i < pts.Count; ++i) Parallel.For(0, pts.Count, i => { Centreline.ClosestPoint(pts[i], out t); m_plane = GetPlane(t); m_plane.RemapToPlaneSpace(pts[i], out m_temp); m_temp.Z = Centreline.GetLength(new Interval(Centreline.Domain.Min, t)); m_output_pts[i] = m_temp; } ); } return(m_output_pts); }