public void ConstructorTest() { // Suppose we were given the function x³ + 2x² - 10x and // we have to find its root, maximum and minimum inside // the interval [-4,3]. First, we express this function // as a lambda expression: Func<double, double> function = x => x * x * x + 2 * x * x - 10 * x; // And now we can create the search algorithm: BrentSearch search = new BrentSearch(function, -4, 3); // Finally, we can query the information we need double max = search.Maximize(); // occurs at -2.61 double min = search.Minimize(); // occurs at 1.27 double root = search.FindRoot(); // occurs at 0.50 Assert.AreEqual(-2.6103173042172645, max); Assert.AreEqual(1.2769840667540548, min); Assert.AreEqual(-0.5, root); }
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)); }
public static EdgeDistance ClosestDistanceBetweenTwoCurves(IMathUtility m,ICurve curve0, ICurve curve1) { var curveDomain = curve1.Domain(); var solver = new BrentSearch (t => { var pt = curve1.PointAt(t); return (curve0.ClosestPointOn(pt).Point - pt).Length(); } , curveDomain[0] , curveDomain[1] ); solver.Minimize(); var param = solver.Solution; var pt1 = curve1.PointAt(param); var pt0 = curve0.ClosestPointOn(pt1).Point; var edge = new Edge3(pt1, pt0); return new EdgeDistance(edge, solver.Value); }