コード例 #1
0
        public static MinimumRadiusResult FindMinimumRadius(this ICurve curve)
        {
            var bound = curve.Domain();

            int    numOfRadius    = 0;
            object radiusObject   = null;
            object locationObject = null;
            object tObject        = null;
            var    hasRadius      = curve.FindMinimumRadius(bound
                                                            , ref numOfRadius
                                                            , ref radiusObject
                                                            , ref locationObject
                                                            , ref tObject);

            if (hasRadius && numOfRadius > 0)
            {
                return(new MinimumRadiusResult
                           (t: ((double[])tObject)[0]
                           , radius: ((double[])radiusObject)[0]
                           , location: ((MathPoint)((object[])locationObject)[0]).ToVector3()));
            }
            else
            {
                return(null);
            }
        }
コード例 #2
0
        public static PointParamWithRayProjection ClosestPointToRay(this ICurve curve, PointDirection3 ray, double tol = 1e-9)
        {
            var bound       = curve.Domain();
            int numOfRadius = 0;

            double[]  radius   = null;
            MathPoint location = null;

            var radiusResult       = curve.FindMinimumRadius();
            var domain             = new RangeDouble(curve.Domain());
            var tessTol            = radiusResult.Radius / 10;
            var closestPointOnEdge = Vector3.Zero;

            for (var i = 0; i < 1; i++)
            {
                var tessPoints = Sequences
                                 .LinSpace(domain.Min, domain.Max, 100)
                                 .Select(curve.PointParamAt).ToList();
                var edges = tessPoints.Buffer(2, 1).Where(buf => buf.Count == 2)
                            .ToList();

                var closestEdge
                    = edges
                      .Select(edge => new { edge, connection = MakeEdge(edge).ShortestEdgeJoining(ray, tol) })
                      .MinBy(o => o.connection.LengthSquared)[0];

                var a = closestEdge.edge[0].T;
                var b = closestEdge.edge[1].T;
                domain  = new RangeDouble(a, b);
                tessTol = tessTol / 10;
            }

            Func <Vector3, Vector3> projectOnRay = p => (p - ray.Point).ProjectOn(ray.Direction) + ray.Point;

            var solver = new BrentSearch(t =>
            {
                var p    = curve.PointAt(t);
                var proj = projectOnRay(p);
                return((p - proj).LengthSquared());
            }, domain.Min, domain.Max);

            solver.Minimize();
            var minT = solver.Solution;

            var pointParam = curve.PointParamAt(minT);

            return(new PointParamWithRayProjection(pointParam, projectOnRay(pointParam.Point)));
        }