internal static Gear PolynomialTrendDetector(TessellatedSolid solid) { // Since gears have different shapes, we need to generate bounding circles in multiple locations // around the gear (bounding cylinde). If any of them are showing a gear, return true. // This makes the code really slow. // To also find negative (internal) gears: // 1. if the closest with negative dot product triangles to bounding cylinder points, it is a positive gear // 2. if the closest with positive dot product triangles to bounding cylinder points, it is a negative gear var section = 5.0; var bC = BoundingCylinder.Run(solid); var kPointsOnSurface = KpointObMidSurfaceOfCylinderGenerator(bC, 1000); for (var i = 0.0; i <= 1; i += 1 / section) { var distancePointToSolidPositive = PointToSolidDistanceCalculator(solid, kPointsOnSurface, bC, i); // in the distance point to solid array, first one is for outer triangle (general case) // the second one is for inner triangle (written for negative gears) List <int> originalInds; distancePointToSolidPositive[0] = FastenerPolynomialTrend.MergingEqualDistances(distancePointToSolidPositive[0], out originalInds, 0.001); //FastenerPolynomialTrend.PlotInMatlab(distancePointToSolidPositive[0]); if (IsGear(distancePointToSolidPositive[0])) { return new Gear { Solid = solid, PointOnAxis = bC.PointOnTheCenterLine, Axis = bC.CenterLineVector, LargeCylinderRadius = bC.Radius, SmallCylinderRadius = bC.Radius - TeethDepthFinder(distancePointToSolidPositive[0]) } } ; // check and see if it is an inner gear List <int> originalInds2; distancePointToSolidPositive[1] = FastenerPolynomialTrend.MergingEqualDistances(distancePointToSolidPositive[1], out originalInds2, 0.001); if (IsGear(distancePointToSolidPositive[1])) { return new Gear { Solid = solid, Type = GearType.Internal, PointOnAxis = bC.PointOnTheCenterLine, Axis = bC.CenterLineVector, LargeCylinderRadius = bC.Radius, SmallCylinderRadius = bC.Radius - TeethDepthFinder(distancePointToSolidPositive[0]) } } ; } return(null); }
internal static Nut PolynomialTrendDetector(TessellatedSolid solid) { // first create the bounding cylinder. // then from the centerline of the cylinder, shoot rays. var bCy = BoundingGeometry.BoundingCylinderDic[solid]; const int k = 500; // I can do the same thing I did for FastenerPolynomial to speed up the code. // To create the sections, they need to be created based on the OBB, then use it in // bounding cylinder. var partitions = new NutBoundingCylinderPartition(solid, 50); var secondPoint = bCy.PointOnTheCenterLine.add(bCy.CenterLineVector.multiply(bCy.Length)); var kPointsBetweenMidPoints = FastenerPolynomialTrend.KpointBtwPointsGenerator(bCy.PointOnTheCenterLine, secondPoint, k); double longestDist; var distancePointToSolid = FastenerPolynomialTrend.PointToSolidDistanceCalculatorWithPartitioning(solid, partitions.Partitions, kPointsBetweenMidPoints, bCy.PerpVector, out longestDist); // one more step: Merge points with equal distances. List <int> originalInds; distancePointToSolid = FastenerPolynomialTrend.MergingEqualDistances(distancePointToSolid, out originalInds, 0.001); int numberOfThreads; int[] threadStartEndPoints; if (FastenerPolynomialTrend.ContainsThread(distancePointToSolid, out numberOfThreads, out threadStartEndPoints)) { return(new Nut { Solid = solid, NumberOfThreads = numberOfThreads, OverallLength = bCy.Length, Diameter = bCy.Radius * 2, Certainty = 1.0 }); } // Plot: //if (hasThread) //FastenerPolynomialTrend.PlotInMatlab(distancePointToSolid); return(null); }