//------------------------------------------------------ // Get Animation Data //------------------------------------------------------ // Perform Bezier interpolation between the key frames private float bezierInterpolation(KeyFrame previous_frame, KeyFrame next_frame, float current_time) { BezierCurveCubic temp_bezier = new BezierCurveCubic(); temp_bezier.StartAnchor = new Vector2(previous_frame.time, previous_frame.data); temp_bezier.FirstControlPoint = previous_frame.bezier_values.Zw; temp_bezier.SecondControlPoint = next_frame.bezier_values.Xy; temp_bezier.EndAnchor = new Vector2(next_frame.time, next_frame.data); return(temp_bezier.CalculatePoint(current_time).Y); }
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; }); }
private void OnSceneGUI() { _curve = target as BezierCurveCubic; _handleTransform = _curve.transform; _handleRotation = Tools.pivotRotation == PivotRotation.Local ? _handleTransform.rotation : Quaternion.identity; var p0 = ShowPoint(0); var p1 = ShowPoint(1); var p2 = ShowPoint(2); var p3 = ShowPoint(3); Handles.color = Color.gray; Handles.DrawLine(p0, p1); Handles.DrawLine(p2, p3); ShowDirections(); Handles.DrawBezier(p0, p3, p1, p2, Color.white, null, 2f); }
public static List <Vector2> nsvg__pathArcTo(Vector2d start, ArcTo a2) { List <Vector2> ret = new List <Vector2>(); Vector2d end = start; // Ported from canvg (https://code.google.com/p/canvg/) double rx, ry, rotx; double x1, y1, x2, y2, cx, cy, dx, dy, d; double x1p, y1p, cxp, cyp, s, sa, sb; double ux, uy, vx, vy, a1, da; double x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0; double[] t = new double[6]; double sinrx, cosrx; bool fa, fs; int ndivs; double hda, kappa; rx = Math.Abs(a2.Radius.Width); ry = Math.Abs(a2.Radius.Height); rotx = a2.xrotation / 180.0f * Math.PI; // x rotation engle fa = a2.LargeArc; fs = a2.SweepClockwise; x1 = start.X; // start point y1 = start.Y; x2 = a2.EndPoint.X; y2 = a2.EndPoint.Y; dx = x1 - x2; dy = y1 - y2; d = Math.Sqrt(dx * dx + dy * dy); if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) { // The arc degenerates to a line //nsvg__lineTo(p, x2, y2); end.X = x2; end.Y = y2; ret.Add((Vector2)end); return(ret); } sinrx = Math.Sin(rotx); cosrx = Math.Cos(rotx); // Convert to center point parameterization. // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes // 1) Compute x1', y1' x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f; y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f; d = sqr(x1p) / sqr(rx) + sqr(y1p) / sqr(ry); if (d > 1) { d = Math.Sqrt(d); rx *= d; ry *= d; } // 2) Compute cx', cy' s = 0.0f; sa = sqr(rx) * sqr(ry) - sqr(rx) * sqr(y1p) - sqr(ry) * sqr(x1p); sb = sqr(rx) * sqr(y1p) + sqr(ry) * sqr(x1p); if (sa < 0.0f) { sa = 0.0f; } if (sb > 0.0f) { s = Math.Sqrt(sa / sb); } if (fa == fs) { s = -s; } cxp = s * rx * y1p / ry; cyp = s * -ry * x1p / rx; // 3) Compute cx,cy from cx',cy' cx = (x1 + x2) / 2.0f + cosrx * cxp - sinrx * cyp; cy = (y1 + y2) / 2.0f + sinrx * cxp + cosrx * cyp; // 4) Calculate theta1, and delta theta. ux = (x1p - cxp) / rx; uy = (y1p - cyp) / ry; vx = (-x1p - cxp) / rx; vy = (-y1p - cyp) / ry; a1 = nsvg__vecang(1.0, 0.0, ux, uy); // Initial angle da = nsvg__vecang(ux, uy, vx, vy); // Delta angle // if (nsvg__vecrat(ux,uy,vx,vy) <= -1.0f) da = Math.PI; // if (nsvg__vecrat(ux,uy,vx,vy) >= 1.0f) da = 0; if (fa) { // Choose large arc if (da > 0.0f) { da = da - 2 * Math.PI; } else { da = 2 * Math.PI + da; } } // Approximate the arc using cubic spline segments. t[0] = cosrx; t[1] = sinrx; t[2] = -sinrx; t[3] = cosrx; t[4] = cx; t[5] = cy; // Split arc into max 90 degree segments. // The loop assumes an iteration per end point (including start and end), this +1. ndivs = (int)(Math.Abs(da) / (Math.PI * 0.5f) + 1.0f); hda = (da / (double)ndivs) / 2.0f; kappa = Math.Abs(4.0f / 3.0f * (1.0f - Math.Cos(hda)) / Math.Sin(hda)); if (da < 0.0f) { kappa = -kappa; } var last = (Vector2)start; for (int i = 0; i <= ndivs; i++) { a = a1 + da * (i / (double)ndivs); dx = Math.Cos(a); dy = Math.Sin(a); nsvg__xformPoint(out x, out y, dx * rx, dy * ry, t); // position nsvg__xformVec(out tanx, out tany, -dy * rx * kappa, dx * ry * kappa, t); // tangent if (i > 0) { BezierCurveCubic b = new BezierCurveCubic((Vector2)last, new Vector2((float)x, (float)y), (Vector2) new Vector2d(px + ptanx, py + ptany), (Vector2) new Vector2d(x - tanx, y - tany)); Vector2 old = b.CalculatePoint(0f); ret.Add(old); var precision = 0.05f; for (float p = precision; p < 1f + precision; p += precision) { Vector2 j = b.CalculatePoint(p); ret.Add(j); } last = b.CalculatePoint(1.0f); } px = x; py = y; ptanx = tanx; ptany = tany; } end.X = x2; end.Y = y2; ret.Add((Vector2)end); return(ret); }
/// <summary> /// Initializes a new instance of the <c>Spline</c> class. /// </summary> /// <param name="fitPoints">Spline fit points.</param> /// <remarks> /// The resulting spline curve will be created from a list of cubic bezier curves that passes through the specified fit points. /// </remarks> public Spline(IEnumerable <Vector3> fitPoints) : this(BezierCurveCubic.CreateFromFitPoints(fitPoints)) { this.creationMethod = SplineCreationMethod.FitPoints; this.fitPoints = new List <Vector3>(fitPoints); }
public void DrawPath(Path path, VBO vbo) { List <List <Vector2> > shapes = new List <List <Vector2> >(); List <Vector2> positions = new List <Vector2>(); List <Vector2> tesselated = new List <Vector2>(); Point position = new Point(); foreach (var op in path.Operations) { var mt = op as MoveTo; if (mt != null) { shapes.Add(positions); positions = new List <Vector2>(); positions.Add(Vec2(mt.Point)); position = mt.Point; continue; } var lt = op as LineTo; if (lt != null) { positions.Add(Vec2(lt.Point)); position = lt.Point; continue; } var at = op as ArcTo; if (at != null) { var p = nsvg.nsvg__pathArcTo((Vector2d)Vec2(position), at); positions.AddRange(p); position = at.Point; continue; } var ct = op as CurveTo; if (ct != null) { if (double.IsNaN(ct.Control1.X) && double.IsNaN(ct.Control1.Y)) { BezierCurveQuadric b = new BezierCurveQuadric(Vec2(position), Vec2(ct.EndPoint), Vec2(ct.Control2)); Vector2 old = b.CalculatePoint(0f); positions.Add(old); var precision = 0.05f; for (float i = precision; i < 1f + precision; i += precision) { Vector2 j = b.CalculatePoint(i); positions.Add(j); old = j; } } else { BezierCurveCubic b = new BezierCurveCubic(Vec2(position), Vec2(ct.EndPoint), Vec2(ct.Control1), Vec2(ct.Control2)); Vector2 old = b.CalculatePoint(0f); positions.Add(old); var precision = 0.05f; for (float i = precision; i < 1f + precision; i += precision) { Vector2 j = b.CalculatePoint(i); positions.Add(j); } } position = ct.EndPoint; } var cp = op as ClosePath; if (cp != null) { if (positions.Count > 0) { positions.Add(positions[0]); shapes.Add(positions); } positions = new List <Vector2>(); position = new Point(); continue; } } shapes.Add(positions); brushcheck(path.Brush); LibTessDotNet.Tess t = new LibTessDotNet.Tess(); List <Vec3> vertices = new List <Vec3>(); foreach (var s in shapes) { ContourVertex[] cv = new ContourVertex[s.Count]; for (int i = 0; i < s.Count; i++) { var v = s[i]; cv[i] = new ContourVertex() { Position = new Vec3() { X = v.X, Y = v.Y } }; } t.AddContour(cv); } var rule = LibTessDotNet.WindingRule.NonZero; if (path.Brush != null) { rule = path.Brush.FillMode == FillMode.EvenOdd ? LibTessDotNet.WindingRule.EvenOdd : LibTessDotNet.WindingRule.NonZero; } t.Tessellate(rule, LibTessDotNet.ElementType.Polygons, 3); for (var i = 0; i < t.ElementCount; i++) { for (var tri = 0; tri < 3; tri++) { vertices.Add(t.Vertices[t.Elements[(i * 3) + tri]].Position); } } for (int i = 0; i < vertices.Count; i++) { tesselated.Add(new Vector2(vertices[i].X, vertices[i].Y)); } var lineshapes = new List <List <Vector2> >(); foreach (var s in shapes) { if (s.Count == 0) { continue; } List <Vector2> add = new List <Vector2>(); for (int i = 0; i < s.Count; i++) { add.Add(new Vector2(s[i].X, s[i].Y)); } lineshapes.Add(add); } if (path.Brush is SolidBrush || path.Pen != null) { if (path.Brush is SolidBrush) { var sb = path.Brush as SolidBrush; for (int i = 0; i < tesselated.Count; i++) { vbo.AddVertex(new Vertex(tesselated[i], color(sb.Color))); } } if (path.Pen != null) { foreach (var list in lineshapes) { foreach (var v in TesselateLines(list, path.Pen)) { vbo.AddVertex(v); } } } } }