public static ExcavationSection Interpolate(ExcavationSection startSection, ExcavationSection endSection, double ratio) { ExcavationSection result = new ExcavationSection(); for (int i = 0; i < Math.Max(startSection.Elements.Count, endSection.Elements.Count); i++) { int startIndex = Math.Min(i, startSection.Elements.Count - 1); int endIndex = Math.Min(i, endSection.Elements.Count - 1); double hStart = startSection.Elements[startIndex].H; double vStart = startSection.Elements[startIndex].V; double hlStart = startSection.Elements[startIndex].HeightLimit; double llStart = startSection.Elements[startIndex].LengthLimit; double hEnd = startSection.Elements[endIndex].H; double vEnd = startSection.Elements[endIndex].V; double hlEnd = startSection.Elements[endIndex].HeightLimit; double llEnd = startSection.Elements[endIndex].LengthLimit; double h = hStart + ratio * (hEnd - hStart); double v = vStart + ratio * (vEnd - vStart); double hl = ((hlStart > 0 && hlEnd > 0) ? hlStart + ratio * (hlEnd - hlStart) : Math.Max(hlStart, hlEnd)); double ll = ((llStart > 0 && llEnd > 0) ? llStart + ratio * (llEnd - llStart) : Math.Max(llStart, llEnd)); ExcavationSectionElement ele = new ExcavationSectionElement(h, v); ele.HeightLimit = hl; ele.LengthLimit = ll; result.Elements.Add(ele); } return(result); }
public void AddSlope(double h, double v, double heightLimit = -1) { ExcavationSectionElement ele = new ExcavationSectionElement(h, v); ele.HeightLimit = heightLimit; Elements.Add(ele); }
public void AddOffset(double lengthLimit) { ExcavationSectionElement ele = new ExcavationSectionElement(1, 0); ele.LengthLimit = lengthLimit; Elements.Add(ele); }
protected static ExcavationSection ExcavateSlopeAtPoint(TriangleNet.Mesh surfaceMesh, ExcavationSection section, Point3d bottomPoint, Vector3d normal) { double xyLen = Math.Sqrt(normal.X * normal.X + normal.Y * normal.Y); ExcavationSection outSection = new ExcavationSection(); foreach (ExcavationSectionElement inputelement in section.Elements) { ExcavationSectionElement element = (ExcavationSectionElement)inputelement.Clone(); element.HasIntersection = false; element.HasTopPoint = false; element.CurrentRatio = double.MaxValue; element.BottomPoint = bottomPoint; // Calculate 3D slope Vector3d slope = new Vector3d(normal.X / xyLen * element.H, normal.Y / xyLen * element.H, element.V); slope = slope / slope.Length; element.Slope = slope; // Intersects slope vectors with surface triangles foreach (TriangleNet.Data.Triangle tri in surfaceMesh.Triangles) { TriangleNet.Data.Vertex v1 = tri.GetVertex(0); TriangleNet.Data.Vertex v2 = tri.GetVertex(1); TriangleNet.Data.Vertex v3 = tri.GetVertex(2); // Intersect the 3D ray from excavation bottom with the triangle double t; Point3d topPoint; bool intersect = RayTriangleIntersection(bottomPoint, slope, new Point3d(v1.X, v1.Y, v1.Attributes[0]), new Point3d(v2.X, v2.Y, v2.Attributes[0]), new Point3d(v3.X, v3.Y, v3.Attributes[0]), out t, out topPoint); double xyDist = double.MaxValue; double zDist = double.MaxValue; if (intersect) { xyDist = new Vector3d(topPoint.X - bottomPoint.X, topPoint.Y - bottomPoint.Y, 0).Length; zDist = topPoint.Z - bottomPoint.Z; } if (!intersect || (element.HeightLimit > 0 && zDist > element.HeightLimit) || (element.LengthLimit > 0 && xyDist > element.LengthLimit)) { t = double.MaxValue; } if (t < element.CurrentRatio) { element.CurrentRatio = t; element.TopPoint = topPoint; element.HasIntersection = true; } } // Create the output section if (element.HasIntersection) { // This element intersected the surface // Add to output section and end calculation element.HasTopPoint = true; outSection.Elements.Add(element); break; } else { // No intersections // Add to output section and continue calculation // Calculate the top point for this element (bottom point for the next element) if (element.HeightLimit > 0) { element.TopPoint = element.BottomPoint + slope * element.HeightLimit / element.V; element.HasTopPoint = true; } else if (element.LengthLimit > 0) { element.TopPoint = element.BottomPoint + slope * element.LengthLimit / element.H; element.HasTopPoint = true; } else { element.HasTopPoint = false; } outSection.Elements.Add(element); bottomPoint = element.TopPoint; } } return(outSection); }