/// <summary> /// </summary> /// <param name="controlPoints"></param> /// <param name="knots">If null equidistant nodes will be generated.</param> /// <param name="parameterCorrection"></param> /// <param name="estimateScreenSpaceDistanceWithoutClip"></param> /// <returns></returns> public static List <Vertex> SampleBSplineCurve(IList <Point3D> controlPoints, IList <double> knots, bool parameterCorrection, Func <Point3D, Point3D, double> estimateScreenSpaceDistanceWithoutClip) { var rawPointsList = new List <Vertex>(); var solver = new DeBoorSolverRecursive3D(controlPoints, knots); if (controlPoints.Count <= 3) { return(rawPointsList); } var bernsteinPolygonLengthNoClip = BezierCurveC0.EstimateScreenSpacePolygonLength( controlPoints, estimateScreenSpaceDistanceWithoutClip, controlPoints.Count - 1, 0 ); var generatedPointsBetween = (int)Math.Ceiling(bernsteinPolygonLengthNoClip); for (var j = 0; j < generatedPointsBetween; ++j) { var t = (double)j / generatedPointsBetween; var lerped = solver.Evaluate(t, parameterCorrection); rawPointsList.Add(new Vertex() { Position = lerped, Color = Colors.White }); } return(rawPointsList); }
protected override void CreateDirectionalSurfaceSampling(Func <Point3D, Point3D, double> estimateScreenDistanceWithoutClip, Func <int, int, Tuple <int, int> > mapping, int subdivisions, List <Vertex> vertices, List <IndexedLine> lines) { var solvers = new DeBoorSolverRecursive3D[4]; for (var i = 0; i < 4; ++i) { var subcontrolPoints = new List <Point3D>(); for (var j = 0; j < 4; ++j) { var mapped = mapping(i, j); subcontrolPoints.Add(ControlPoints[mapped.Item1 + mapped.Item2 * 4].Position); } solvers[i] = new DeBoorSolverRecursive3D(subcontrolPoints); } for (var i = 0; i < subdivisions; ++i) { var t = (double)i / (subdivisions - 1); var subdivisionControlPoints = new List <Point3D>(); for (var j = 0; j < 4; ++j) { subdivisionControlPoints.Add(solvers[j].Evaluate(t, true)); } var sampled = BezierCurveC2.SampleBSplineCurve(subdivisionControlPoints, null, true, estimateScreenDistanceWithoutClip); if (sampled.Count <= 1) { continue; } var sampledLines = Enumerable.Range(vertices.Count, sampled.Count - 1) .Select(idx => new IndexedLine(idx, idx + 1)) .ToList(); vertices.AddRange(sampled); lines.AddRange(sampledLines); } }
public Vector3D DerivativeU(double u, double v) { var recalculatedRowPoints = new List <Point3D>(); var dataRows = ControlPoints.Count / (3 + SegmentsU); for (var column = 0; column < SegmentsU + 3; ++column) { var rowControlPoints = new List <Point3D>(); for (var row = 0; row < SegmentsV + 3; ++row) { var index = (3 + SegmentsU) * (row % dataRows) + column; rowControlPoints.Add(ControlPoints[index]); } var solver = new DeBoorSolverRecursive3D(rowControlPoints); var calculatedPoint = solver.Evaluate(v, true); recalculatedRowPoints.Add(calculatedPoint); } var uSolver = new DeBoorSolverRecursive3D(recalculatedRowPoints); return(uSolver.Derivative(u, true)); }