public static TweenFunc<float> CubicBezier (float mx1, float my1, float mx2, float my2) { var curve = new BezierCurveCubic( new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(mx1, my1), new Vector2(mx2, my2) ); return (from, to, t) => { return from + (to - from) * curve.CalculatePoint(t).Y; }; }
/// <summary> /// Tessellates the path. /// </summary> /// <param name="path">The path.</param> public void TessellatePath(PathGeometry path) { _vertexList.Clear(); _tesselator.EmptyCache(); _tesselator.BeginPolygon(); switch(path.FillRule) { case FillRule.EvenOdd: _tesselator.WindingRule = Tesselator.Tesselator.WindingRuleType.Odd; break; case FillRule.Nonzero: _tesselator.WindingRule = Tesselator.Tesselator.WindingRuleType.NonZero; break; default: throw new ArgumentOutOfRangeException(); } foreach (var figure in path.Figures) { _tesselator.BeginContour(); foreach (var seg in figure.Segments) { if (seg is PolyLineSegment) { var polyline = seg as PolyLineSegment; polyline.Points.ForEach(AddPoint); } else if (seg is LineSegment) { AddPoint((seg as LineSegment).Point); } else if (seg is PolyBezierSegment) { var polybezier = (PolyBezierSegment) seg; var bezierCurve = new BezierCurve(polybezier.Points.Select(p => new Vector2((float) p.X, (float) p.Y))); Enumerable .Range(1, 10) .Select(i => bezierCurve.CalculatePoint(1.0f/i)) .ForEach(p => AddPoint(new Point(p.X, p.Y))); } else if (seg is BezierSegment) { var polybezier = (BezierSegment)seg; var bezierCurve = new BezierCurveCubic( LastPoint(), new Vector2((float) polybezier.Point3.X, (float) polybezier.Point3.Y), new Vector2((float) polybezier.Point1.X, (float) polybezier.Point1.Y), new Vector2((float) polybezier.Point2.X, (float) polybezier.Point2.Y) ); Enumerable .Range(1, 10) .Select(i => bezierCurve.CalculatePoint(1.0f / i)) .ForEach(p => AddPoint(new Point(p.X, p.Y))); } else { throw new ApplicationException(string.Format("segment type {0} not supported.", seg)); } } _tesselator.EndContour(); } _tesselator.EndPolygon(); }