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);
        }
예제 #2
0
        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);
        }