public bool Insert(MarkGeometryLine line) { if ( !( GeometricArithmeticModule.IsWithin2D(line.StartPoint, Boundary.Extents) && GeometricArithmeticModule.IsWithin2D(line.EndPoint, Boundary.Extents) ) ) { return(false); } // ensure quads exist if (!ChildrenExists) { var radius = 0.5 * SubSize; NorthWest = new ContourQuadTree( Boundary.Extents.MinX + radius, // west Boundary.Extents.MaxY - radius, // north SubSize ); NorthEast = new ContourQuadTree( Boundary.Extents.MaxX - radius, // east Boundary.Extents.MaxY - radius, // north SubSize ); SouthWest = new ContourQuadTree( Boundary.Extents.MinX + radius, // west Boundary.Extents.MinY + radius, // south SubSize ); SouthEast = new ContourQuadTree( Boundary.Extents.MaxX - radius, // east Boundary.Extents.MinY + radius, // south SubSize ); ChildrenExists = true; } if ( (line.Length <= MinSize) || !( NorthWest.Insert(line) || NorthEast.Insert(line) || SouthWest.Insert(line) || SouthEast.Insert(line) ) ) { Segments.Add(line); } return(true); }
private IntersectionsBinaryTree Intersect(MarkGeometryLine line, LineEquation equation) { if (!equation.PassesThroughRect(Boundary)) { return(null); } // using binary tree to sort points relative to the line's starting point var intersections = new IntersectionsBinaryTree(line.StartPoint); if (ChildrenExists) { IntersectionsBinaryTree childIntersections; if ((childIntersections = NorthWest.Intersect(line)) != null) { intersections.InsertRange(childIntersections); } if ((childIntersections = NorthEast.Intersect(line)) != null) { intersections.InsertRange(childIntersections); } if ((childIntersections = SouthWest.Intersect(line)) != null) { intersections.InsertRange(childIntersections); } if ((childIntersections = SouthEast.Intersect(line)) != null) { intersections.InsertRange(childIntersections); } } MarkGeometryPoint intersection; for (int i = 0; i < Segments.Count; i++) { if (( intersection = GeometricArithmeticModule.CalculateIntersection2D( line, Segments[i] )) != null ) { intersections.Insert(intersection); } } return(intersections); }
public LineEquation(MarkGeometryLine line) { Gradient = line.Gradient; AlternateX = line.StartPoint.X; AlternateY = line.StartPoint.Y; if (Math.Abs(line.StartPoint.X) < tolerance) { YIntercept = line.StartPoint.Y; } else { YIntercept = line.StartPoint.Y - (Gradient * line.StartPoint.X); } }
public void GenerateFiducialPattern(double radius = 2.5, int numOfLines = 4) { _fiducialPattern = new List <IMarkGeometry>(); var baseLine = new MarkGeometryLine(new MarkGeometryPoint(-radius, 0), new MarkGeometryPoint(radius, 0)); var transform = GeometricArithmeticModule.GetRotationTransformationMatrix( 0, 0, Math.PI / numOfLines ); for (int i = 0; i < numOfLines; i++) { _fiducialPattern.Add((IMarkGeometry)baseLine.Clone()); baseLine.Transform(transform); } _fiducialPattern.Add(new MarkGeometryCircle(radius)); }
private static (string Layer, IMarkGeometry Geometry) TryParseLine(StreamReader readerIn) { string layerName = null; IMarkGeometry geometry = null; while (true) { var(found, line) = SkipUntil(readerIn, MatchLayerOrLine); if (!found) { break; } switch (MatchLayerOrLine.Match(line).Value.Trim()) { case "8": layerName = readerIn.ReadLine(); break; case "AcDbLine": var startPoint = TryParsePoint(readerIn); var endPoint = TryParsePoint(readerIn); geometry = new MarkGeometryLine(startPoint, endPoint) { LayerName = layerName }; return(layerName, geometry); default: throw new Exception($"Matched circle attribute is not supported: `{line}`"); } } return(layerName, geometry); }
private (string LayerName, MarkGeometryLine Line) ParseLine(AdvancedLineStreamReader readerIn) { var(success, layerName) = ReadLayerName(readerIn, "AcDbLine"); if (success) { var result = readerIn.FindConsecutiveLines( "100", "AcDbLine" ); if (!result.Success) { return(null, null); } } var line = new MarkGeometryLine( ReadPointFast(readerIn), ReadPointFast(readerIn) ); return(layerName, line); }
protected static double[] ToDouble(MarkGeometryLine line) { return(new double[] { line.StartPoint.X, line.StartPoint.Y, line.EndPoint.X, line.EndPoint.Y }); }
public bool GenerateHatches(MHatchSettings settings) { HatchLines.Clear(); _totalHatchesJumpDistance = 0; _totalHatchesMarkDistance = 0; var lines = new List <MarkGeometryLine>(); var angleRad = GeometricArithmeticModule.ToRadians(settings.Angle); var size = Extents.Hypotenuse; var howmany = (int)Math.Ceiling(size / settings.Pitch); var yStart = Extents.Centre.Y - (0.5 * size); // generate lines to calculate intersections for hatch if (settings.Style == HatchStyle.RASTER || settings.Style == HatchStyle.RASTER_GRID) { for (int i = 0; i < howmany; i++) { double y = yStart + (i * settings.Pitch); var line = new MarkGeometryLine( new MarkGeometryPoint( -size + Extents.Centre.X, y ), new MarkGeometryPoint( size + Extents.Centre.X, y ) ); // apply angular rotation GeometricArithmeticModule.Rotate(line, 0, 0, angleRad, Extents.Centre.X, Extents.Centre.Y, Extents.Centre.Z); lines.Add(line); } } else if (settings.Style == HatchStyle.SERPENTINE || settings.Style == HatchStyle.SERPENTINE_GRID) { for (int i = 0; i < howmany; i++) { double y = yStart + (i * settings.Pitch); if (i % 2 == 0) { var line = new MarkGeometryLine( new MarkGeometryPoint( -size + Extents.Centre.X, y ), new MarkGeometryPoint( size + Extents.Centre.X, y ) ); // apply angular rotation GeometricArithmeticModule.Rotate(line, 0, 0, angleRad, Extents.Centre.X, Extents.Centre.Y, Extents.Centre.Z); lines.Add(line); } else { var line = new MarkGeometryLine( new MarkGeometryPoint( size + Extents.Centre.X, y ), new MarkGeometryPoint( -size + Extents.Centre.X, y ) ); // apply angular rotation GeometricArithmeticModule.Rotate(line, 0, 0, angleRad, Extents.Centre.X, Extents.Centre.Y, Extents.Centre.Z); lines.Add(line); } } } // duplicate lines if using grid var perpendicularAngleForGridLines = GeometricArithmeticModule.ToRadians(90); if (settings.Style == HatchStyle.RASTER_GRID || settings.Style == HatchStyle.SERPENTINE_GRID) { int startIndex = lines.Count - 1; for (int i = startIndex; i >= 0; i--) { var ln = (MarkGeometryLine)lines[i].Clone(); GeometricArithmeticModule.Rotate(ln, 0, 0, perpendicularAngleForGridLines, Extents.Centre.X, Extents.Centre.Y, Extents.Centre.Z); lines.Add(ln); } } // used to track jumps MarkGeometryPoint lastPoint = null; // generate hatch lines with extension for (int i = 0; i < lines.Count; i++) { List <MarkGeometryPoint> intersections = _contourQuadTree.Intersect(lines[i])?.ToList(); if (intersections == null) { continue; } int startIndex = (settings.Invert) ? 1 : 0; int endIndex = intersections.Count - 1; while (startIndex < endIndex) { var hatch = new MarkGeometryLine( intersections[startIndex], intersections[startIndex + 1] ); HatchLines.Add(hatch); // increase mark and jump distance if (lastPoint != null) { _totalHatchesJumpDistance += GeometricArithmeticModule.ABSMeasure2D( lastPoint, hatch.StartPoint ); } _totalHatchesMarkDistance += hatch.Length; lastPoint = hatch.EndPoint; startIndex += 2; } } return(true); }
public IntersectionsBinaryTree Intersect(MarkGeometryLine line) { return(Intersect(line, new LineEquation(line))); }
private static void TestQuadTree() { var _slicer = new MSTLSlicer(); _slicer.Load(@"C:\MSOLV\STLs\Ice Cream Type 2.stl"); //_slicer.Load(@"C:\MSOLV\STLs\tray.stl"); var slices = _slicer.Slice(); IEnumerable <MVertex> contour = slices[7][0].ToVertices().Concat(slices[5][0].ToVertices()); //IEnumerable<MVertex> contour = slices[5][1].ToVertices(); var reference = ToPath(contour); var intersectingLine = new MarkGeometryLine( reference.Extents.MinimumPoint, reference.Extents.MaximumPoint ); List <MarkGeometryPoint> controlResults = new List <MarkGeometryPoint>(); List <MarkGeometryPoint> quadTreeResults = new List <MarkGeometryPoint>(); var lines = ToLines(contour); var contourQuadTree = new ContourQuadTree(contour); Console.WriteLine( PerformanceHelper.Compare( () => { // setup up controlResults.Clear(); MarkGeometryPoint intersection; for (int i = 0; i < lines.Count; i++) { if (( intersection = GeometricArithmeticModule.CalculateIntersection2D( intersectingLine, lines[i] )) != null ) { controlResults.Add(intersection); } } }, () => { // setup up quadTreeResults.Clear(); quadTreeResults = contourQuadTree.Intersect(intersectingLine).ToList(); }, tagA: "Lines (Control)", tagB: "Quad Tree" ) ); Println("Control", controlResults); Println("Quad Tree Intersections", quadTreeResults); contourQuadTree.SaveImage(@"C:\Users\Chibuike.Okpaluba\Downloads\quad_tree_v2.png"); }