/// <summary> /// Tries to fit single Bezier curve to the points in [first ... last]. Destroys anything in <see cref="_u"/> in the process. /// Assumes there are at least two points to fit. /// </summary> /// <param name="first">Index of first point to consider.</param> /// <param name="last">Index of last point to consider (inclusive).</param> /// <param name="tanL">Tangent at teh start of the curve ("left").</param> /// <param name="tanR">Tangent on the end of the curve ("right").</param> /// <param name="curve">The fitted curve.</param> /// <param name="split">Point at which to split if this method returns false.</param> /// <returns>true if the fit was within error tolerence, false if the curve should be split. Even if this returns false, curve will contain /// a curve that somewhat fits the points; it's just outside error tolerance.</returns> protected bool FitCurve(int first, int last, VECTOR tanL, VECTOR tanR, out CubicBezier curve, out int split) { List<VECTOR> pts = _pts; int nPts = last - first + 1; if (nPts < 2) { throw new InvalidOperationException("INTERNAL ERROR: Should always have at least 2 points here"); } else if (nPts == 2) { // if we only have 2 points left, estimate the curve using Wu/Barsky VECTOR p0 = pts[first]; VECTOR p3 = pts[last]; FLOAT alpha = VectorHelper.Distance(p0, p3) / 3; VECTOR p1 = (tanL * alpha) + p0; VECTOR p2 = (tanR * alpha) + p3; curve = new CubicBezier(p0, p1, p2, p3); split = 0; return true; } else { split = 0; ArcLengthParamaterize(first, last); // initially start u with a simple chord-length paramaterization curve = default(CubicBezier); for (int i = 0; i < MAX_ITERS + 1; i++) { if (i != 0) Reparameterize(first, last, curve); // use newton's method to find better parameters (except on first run, since we don't have a curve yet) curve = GenerateBezier(first, last, tanL, tanR); // generate the curve itself FLOAT error = FindMaxSquaredError(first, last, curve, out split); // calculate error and get split point (point of max error) if (error < _squaredError) return true; // if we're within error tolerance, awesome! } return false; } }
public void WriteBeziers(CubicBezier[] beziers, Dictionary<CubicBezier, PathStyle> styles, int pointRadius, int lineWidth) { foreach (var bezier in beziers) { double actualLineWidth = lineWidth; if (styles.ContainsKey(bezier)) actualLineWidth = styles[bezier].Thickness; System.IO.File.AppendAllText(mFullFileName, CreateSvgBezierPath(bezier, pointRadius, actualLineWidth)); } }
public void Reset() { EditorOnlyToolSettings = new ToolSettings(); CubicBezier localBezier = new CubicBezier( new Vector3(0.5f, 0f, 0f), new Vector3(1.0f, 0.5f, 0f), new Vector3(0.5f, 1.0f, 0.5f), new Vector3(0f, 0.5f, 0.5f) ); Path = new CubicBezierPath(this.transform, localBezier); }
public TrackNodeCurve (CubicBezier cubicBezier, TrackSegmentModify segmentModify,bool beginning) { this._cubicBezier = cubicBezier; this._segmentModify = segmentModify; if(!beginning) P0 = AddNode ( _segmentModify.TrackSegment.transform.TransformPoint (_cubicBezier.p0),TrackCurveNode.NodeType.PO); P1 = AddNode (_segmentModify.TrackSegment.transform.TransformPoint (_cubicBezier.p1),TrackCurveNode.NodeType.P1); P2 = AddNode (_segmentModify.TrackSegment.transform.TransformPoint (_cubicBezier.p2),TrackCurveNode.NodeType.P2); P3 = AddNode (_segmentModify.TrackSegment.transform.TransformPoint (_cubicBezier.p3),TrackCurveNode.NodeType.P3); }
public TrackNodeCurve (CubicBezier cubicBezier, TrackSegmentModify segmentModify,Grouping grouping) { this.Group = grouping; this.cubicBezier = cubicBezier; this.SegmentModify = segmentModify; P0 = AddTrackCurveNode ( SegmentModify.TrackSegment.transform.TransformPoint (cubicBezier.p0),TrackNode.NodeType.PO ); P1 = AddTrackCurveNode (SegmentModify.TrackSegment.transform.TransformPoint (cubicBezier.p1), TrackNode.NodeType.P1); P2 = AddTrackCurveNode (SegmentModify.TrackSegment.transform.TransformPoint (cubicBezier.p2),TrackNode.NodeType.P2); P3 = AddTrackCurveNode (SegmentModify.TrackSegment.transform.TransformPoint (cubicBezier.p3),TrackNode.NodeType.P3); if ((grouping == Grouping.End || grouping == Grouping.Both) && SegmentModify.GetNextSegment(true) == null) { ExtrudeNode = AddExtrudeNode (SegmentModify.TrackSegment.transform.TransformPoint (cubicBezier.p3) + SegmentModify.TrackSegment.getTangentPoint(1f)*.3f); } }
private string CreateSvgBezierPath(CubicBezier bezier, int pointRadius, double lineWidth) { string result = ""; result += string.Format(GetCI(), " <path d=\"M{0},{1} C{2},{3} {4},{5} {6},{7}\" fill=\"none\" stroke=\"red\" stroke-width=\"{8}\" />\r\n", TraX(bezier.P0.x), TraY(bezier.P0.y), TraX(bezier.C0.x), TraY(bezier.C0.y), TraX(bezier.C1.x), TraY(bezier.C1.y), TraX(bezier.P1.x), TraY(bezier.P1.y), lineWidth); //result += " <g fill=\"#8888FF\" >\r\n"; //result += CreateSvgPoint(bezier.P0, pointRadius); //result += CreateSvgPoint(bezier.P1, pointRadius); //result += " </g>\r\n"; //result += " <g fill=\"#FF8888\" >\r\n"; //result += CreateSvgPoint(bezier.C0, pointRadius); //result += CreateSvgPoint(bezier.C1, pointRadius); //result += " </g>\r\n"; return result; }
public void Awake() { cubicBezier = target as CubicBezier; }
public List <CubicBezier> FitBezier(List <Vector3> pts, List <float> times, bool useRdp = true) { AllInputPoints = new List <Vector3d>(pts.Count); foreach (var pt in pts) { AllInputPoints.Add(pt); } inputPointsTree = new PointAABBTree3(new PointSet(AllInputPoints.ToArray())); AllInputPointTimes = times; if (useRdp) { var reduced = CurvePreprocess.RdpReduce(pts, Globals.RDP_ERROR, out List <int> keepIdx); PointsKeepIdx = keepIdx; InputPoints = reduced; Curves = new List <CubicBezier>(CurveFit.Fit(reduced, Globals.BEZIER_FIT_MAX_ERROR)); } else { InputPoints = pts; Curves = new List <CubicBezier>(CurveFit.Fit(pts, Globals.BEZIER_FIT_MAX_ERROR)); } Curves[0] = new CubicBezier( Curves[0].p0, Curves[0].p0 + (Curves[0].p1 - Curves[0].p0).magnitude * Vector3.forward, Curves[0].p2, Curves[0].p3); if (Curves.Count == 0) { ControlPoints = new Vector3[0]; } else { ControlPoints = new Vector3[1 + 3 * Curves.Count]; ControlPoints[0] = Curves[0].p0; } for (int i = 0; i < Curves.Count; ++i) { ControlPoints[3 * i + 1] = Curves[i].p1; ControlPoints[3 * i + 2] = Curves[i].p2; ControlPoints[3 * i + 3] = Curves[i].p3; } float[] cpData = new float[ControlPoints.Length * 3]; for (int i = 0; i < ControlPoints.Length; ++i) { cpData[3 * i + 0] = ControlPoints[i].x; cpData[3 * i + 1] = ControlPoints[i].y; cpData[3 * i + 2] = ControlPoints[i].z; } if (_path != IntPtr.Zero) { _DeleteUnmanagedPathObject(_path); } _path = _CreateUnmanagedPathObject(cpData, ControlPoints.Length); CacheArcLength(); if (times.Count == 0) { paramToTimeCache = paramToArcLengthCache; } else { CacheTime(); } InputPointArcLengths = new List <float>(InputPoints.Count); foreach (var pt in InputPoints) { var res = GetClosestPoint(pt, out Vector3 closest, out int bezierIdx, out float param); if (res) { InputPointArcLengths.Add(GetArcLengthFromSplineParam(bezierIdx, param)); } else { throw new Exception("Something horrible happened!"); } } return(Curves); }
/// <summary> /// Initialises the projectile with the given forward vector /// </summary> /// <param name="forwardVector"></param> public void OnProjectileStart(Vector3 forwardVector) { _bezierCurve = new CubicBezier(curveControlPoints); _startToEndDistance = Vector3.Distance(curveControlPoints[0], curveControlPoints[3]); }
private static void OnPathSegment(CsPotrace.Curve Curve, double oX, double oY, double scale, List <string> rv, Graphics g) { if (double.IsNaN(Curve.LinearLenght)) // problem? { return; } if (Curve.Kind == CsPotrace.CurveKind.Line) { //trace line if (g != null) { g.DrawLine(Pens.DarkGray, (float)Curve.A.X, (float)Curve.A.Y, (float)Curve.B.X, (float)Curve.B.Y); } rv.Add(String.Format("G1 X{0} Y{1}", formatnumber(Curve.B.X + oX, scale), formatnumber(Curve.B.Y + oY, scale))); } if (Curve.Kind == CsPotrace.CurveKind.Bezier) { CubicBezier cb = new CubicBezier(new Vector2((float)Curve.A.X, (float)Curve.A.Y), new Vector2((float)Curve.ControlPointA.X, (float)Curve.ControlPointA.Y), new Vector2((float)Curve.ControlPointB.X, (float)Curve.ControlPointB.Y), new Vector2((float)Curve.B.X, (float)Curve.B.Y)); if (g != null) { g.DrawBezier(Pens.Green, AsPointF(cb.P1), AsPointF(cb.C1), AsPointF(cb.C2), AsPointF(cb.P2)); } try { List <BiArc> bal = Algorithm.ApproxCubicBezier(cb, 5, 2); if (bal != null) //può ritornare null se ha troppi punti da processare { foreach (BiArc ba in bal) { if (!double.IsNaN(ba.A1.Length) && !double.IsNaN(ba.A1.LinearLength)) { rv.Add(GetArcGC(ba.A1, oX, oY, scale, g)); } if (!double.IsNaN(ba.A2.Length) && !double.IsNaN(ba.A2.LinearLength)) { rv.Add(GetArcGC(ba.A2, oX, oY, scale, g)); } } } else //same as exception { if (g != null) { g.DrawLine(Pens.DarkGray, (float)Curve.A.X, (float)Curve.A.Y, (float)Curve.B.X, (float)Curve.B.Y); } rv.Add(String.Format("G1 X{0} Y{1}", formatnumber(Curve.B.X + oX, scale), formatnumber(Curve.B.Y + oY, scale))); } } catch { if (g != null) { g.DrawLine(Pens.DarkGray, (float)Curve.A.X, (float)Curve.A.Y, (float)Curve.B.X, (float)Curve.B.Y); } rv.Add(String.Format("G1 X{0} Y{1}", formatnumber(Curve.B.X + oX, scale), formatnumber(Curve.B.Y + oY, scale))); } } }
public void MakeSmoothPath() { if (this.isValidSmooth) { return; } this.isValidSmooth = true; //-------- if (contPoints.Count == 0) { return; } //return; //-------- //lets smooth it //string str1 = dbugDumpPointsToString(contPoints); //string str2 = dbugDumpPointsToString2(contPoints); //var data2 = CurvePreprocess.RdpReduce(contPoints, 2); var data2 = contPoints; CubicBezier[] cubicBzs = CurveFit.Fit(data2, 8); //PathWriter pWriter = new PathWriter(); //pWriter.StartFigure(); //int j = cubicBzs.Length; //for (int i = 0; i < j; ++i) //{ // CubicBezier bz = cubicBzs[i]; // pWriter.MoveTo(bz.p0.x, bz.p0.y); // pWriter.LineTo(bz.p0.x, bz.p0.y); // pWriter.Curve4(bz.p1.x, bz.p1.y, // bz.p2.x, bz.p2.y, // bz.p3.x, bz.p3.y); //} //pWriter.CloseFigureCCW(); vxs = new VertexStore(); int j = cubicBzs.Length; //1. if (j > 0) { //1st CubicBezier bz0 = cubicBzs[0]; vxs.AddMoveTo(bz0.p0.x, bz0.p0.y); vxs.AddLineTo(bz0.p0.x, bz0.p0.y); vxs.AddP3c(bz0.p1.x, bz0.p1.y); vxs.AddP3c(bz0.p2.x, bz0.p2.y); vxs.AddLineTo(bz0.p3.x, bz0.p3.y); //------------------------------- for (int i = 1; i < j; ++i) //start at 1 { CubicBezier bz = cubicBzs[i]; vxs.AddP3c(bz.p1.x, bz.p1.y); vxs.AddP3c(bz.p2.x, bz.p2.y); vxs.AddLineTo(bz.p3.x, bz.p3.y); } //------------------------------- //close vxs.AddLineTo(bz0.p0.x, bz0.p0.y); } vxs.AddCloseFigure(); VertexStore v2 = new VertexStore(); cflat.MakeVxs(vxs, v2); vxs = v2; }
/// <summary> /// Computes the maximum squared distance from a point to the curve using the current parameterization. /// </summary> protected FLOAT FindMaxSquaredError(int first, int last, CubicBezier curve, out int split) { List<VECTOR> pts = _pts; List<FLOAT> u = _u; int s = (last - first + 1) / 2; int nPts = last - first + 1; FLOAT max = 0; for (int i = 1; i < nPts; i++) { VECTOR v0 = pts[first + i]; VECTOR v1 = curve.Sample(u[i]); FLOAT d = VectorHelper.DistanceSquared(v0, v1); if (d > max) { max = d; s = i; } } // split at point of maximum error split = s + first; if (split <= first) split = first + 1; if (split >= last) split = last - 1; return max; }
private static void OnPathSegment(Curve Curve, string lOn, double oX, double oY, double scale, List <string> rv, Graphics g, int idx) { string onCode = idx == 0 ? $" {lOn}" : ""; if (double.IsNaN(Curve.LinearLength)) // problem? { return; } if (Curve.Kind == CurveKind.Line) { //trace line g?.DrawLine(Pens.DarkGray, (float)Curve.A.X, (float)Curve.A.Y, (float)Curve.B.X, (float)Curve.B.Y); rv.Add($"G1 X{FormatNumber(Curve.B.X + oX, scale)} Y{FormatNumber(Curve.B.Y + oY, scale)}{onCode}"); } if (Curve.Kind == CurveKind.Bezier) { CubicBezier cb = new CubicBezier(new Vector2((float)Curve.A.X, (float)Curve.A.Y), new Vector2((float)Curve.ControlPointA.X, (float)Curve.ControlPointA.Y), new Vector2((float)Curve.ControlPointB.X, (float)Curve.ControlPointB.Y), new Vector2((float)Curve.B.X, (float)Curve.B.Y)); g?.DrawBezier(Pens.Green, AsPointF(cb.P1), AsPointF(cb.C1), AsPointF(cb.C2), AsPointF(cb.P2)); try { List <BiArc> bal = Algorithm.ApproxCubicBezier(cb, 5, 2); if (bal != null) //può ritornare null se ha troppi punti da processare { foreach (BiArc ba in bal) { if (!double.IsNaN(ba.A1.Length) && !double.IsNaN(ba.A1.LinearLength)) { rv.Add($"{GetArcGC(ba.A1, oX, oY, scale, g)}{onCode}"); } if (!double.IsNaN(ba.A2.Length) && !double.IsNaN(ba.A2.LinearLength)) { rv.Add($"{GetArcGC(ba.A2, oX, oY, scale, g)}{onCode}"); } } } else //same as exception { g?.DrawLine(Pens.DarkGray, (float)Curve.A.X, (float)Curve.A.Y, (float)Curve.B.X, (float)Curve.B.Y); rv.Add( $"G1 X{FormatNumber(Curve.B.X + oX, scale)} Y{FormatNumber(Curve.B.Y + oY, scale)}{onCode}"); } } catch { g?.DrawLine(Pens.DarkGray, (float)Curve.A.X, (float)Curve.A.Y, (float)Curve.B.X, (float)Curve.B.Y); rv.Add($"G1 X{FormatNumber(Curve.B.X + oX, scale)} Y{FormatNumber(Curve.B.Y + oY, scale)}{onCode}"); } } }
public EffectParamI(int a, int b, CubicBezier curve) : base(a, b, (x, y, t) => (int)(curve.Sample(t) * (y - x)) + x) { }
protected override void RenderPath(FillStyle fs, StrokeStyle ss, List <IShapeData> sh, bool silverlight) { // <Path Fill="#FFFF0000" // StrokeThickness="0.00491913" StrokeLineJoin="Round" Stroke="#FF014393" // Data="M 196.667,4L 388.667,100L 388.667,292L 196.667,388L 4.66669,292L 4.66669,100L 196.667,4 Z "/> if (sh.Count == 0) { return; } xw.WriteStartElement("path"); if (fs != null) { switch (fs.FillType) { case FillType.Solid: Color c = ((SolidFill)fs).Color; xw.WriteStartAttribute("fill"); xw.WriteColor(c); xw.WriteEndAttribute(); // try to clean up faint edges if (ss == null && c != new Color(0xFF, 0xFF, 0xFF) && c.A != 0) { ss = new SolidStroke(0.3F, c); } break; case FillType.Linear: case FillType.Radial: case FillType.Focal: GradientFill gf = (GradientFill)fs; // fill="url(#lg)" xw.WriteStartAttribute("fill"); xw.WriteValue("url(#gf_" + gf.TagId + ")"); xw.WriteEndAttribute(); break; case FillType.Image: ImageFill img = (ImageFill)fs; if (img.IsTiled) { //isTiledBitmap = true; } break; } } else { xw.WriteStartAttribute("fill"); xw.WriteValue("none"); xw.WriteEndAttribute(); } if (ss != null) { if (ss is SolidStroke) { // StrokeThickness="3" StrokeLineJoin="Round" Stroke="#FF014393" // StrokeStartLineCap="Round" // StrokeEndLineCap="Round" SolidStroke st = (SolidStroke)ss; if (st.LineWidth != 0.3f) { xw.WriteStartAttribute("stroke-width"); xw.WriteFloat(st.LineWidth); xw.WriteEndAttribute(); } xw.WriteStartAttribute("stroke"); xw.WriteColor(st.Color); xw.WriteEndAttribute(); } } // todo: this is pre defined in svg //if (isTiledBitmap) //{ // //<Path.Fill> // // <ImageBrush ImageSource="Resources\bmp_1.jpg" TileMode="Tile" RelativeTransform=".2,0,0,.2,0,0"/> // //</Path.Fill> // ImageFill img = (ImageFill)fs; // xw.WriteStartElement("Path.Fill"); // xw.WriteStartElement("ImageBrush"); // xw.WriteStartAttribute("ImageSource"); // xw.WriteValue(img.ImagePath); // xw.WriteEndAttribute(); // if (!silverlight) // { // xw.WriteStartAttribute("TileMode"); // xw.WriteValue("Tile"); // xw.WriteEndAttribute(); // } // Matrix pMatrix = ApplyMatrixToShape(sh, img.Matrix, images[img.ImagePath].StrokeBounds); // //Matrix pMatrix = ApplyMatrixToImage(img.Matrix, images[img.ImagePath].Bounds); // xw.WriteStartAttribute("RelativeTransform"); // xw.WriteMatrix(pMatrix); // //xw.WriteMatrix(img.Matrix); // xw.WriteEndAttribute(); // xw.WriteEndElement(); // Path.Fill // xw.WriteEndElement(); // ImageBrush //} xw.WriteStartAttribute("d"); xw.WriteMoveTo(sh[0].StartPoint); Point lastPoint = sh[0].StartPoint; for (int i = 0; i < sh.Count; i++) { IShapeData sd = sh[i]; if (lastPoint != sd.StartPoint) { xw.WriteMoveTo(sd.StartPoint); } switch (sd.SegmentType) { case SegmentType.Line: xw.WriteLineTo(sd.EndPoint); lastPoint = sd.EndPoint; break; case SegmentType.CubicBezier: CubicBezier cb = (CubicBezier)sd; xw.WriteCubicCurveTo(cb.Control0, cb.Control1, cb.Anchor1); lastPoint = cb.EndPoint; break; case SegmentType.QuadraticBezier: QuadBezier qb = (QuadBezier)sd; xw.WriteQuadraticCurveTo(qb.Control, qb.Anchor1); lastPoint = qb.EndPoint; break; } } xw.WriteEndAttribute(); xw.WriteEndElement(); // Path }
public void WriteGradientDefinition(Shape shape) { GradientFill gf = (GradientFill)shape.Fill; gf.TagId = gradientCounter++; List <IShapeData> shapeData = shape.ShapeData; float minX = float.PositiveInfinity; float minY = float.PositiveInfinity; float maxX = float.NegativeInfinity; float maxY = float.NegativeInfinity; Point lastPoint = shapeData[0].StartPoint; for (int i = 0; i < shapeData.Count; i++) { IShapeData sd = shapeData[i]; switch (sd.SegmentType) { case SegmentType.Line: lastPoint = sd.EndPoint; break; case SegmentType.CubicBezier: CubicBezier cb = (CubicBezier)sd; lastPoint = cb.EndPoint; minX = Math.Min(minX, cb.Control0.X); maxX = Math.Max(maxX, cb.Control0.X); minY = Math.Min(minY, cb.Control0.Y); maxY = Math.Max(maxY, cb.Control0.Y); minX = Math.Min(minX, cb.Control1.X); maxX = Math.Max(maxX, cb.Control1.X); minY = Math.Min(minY, cb.Control1.Y); maxY = Math.Max(maxY, cb.Control1.Y); break; case SegmentType.QuadraticBezier: QuadBezier qb = (QuadBezier)sd; lastPoint = qb.EndPoint; minX = Math.Min(minX, qb.Control.X); maxX = Math.Max(maxX, qb.Control.X); minY = Math.Min(minY, qb.Control.Y); maxY = Math.Max(maxY, qb.Control.Y); break; } minX = Math.Min(minX, sd.StartPoint.X); maxX = Math.Max(maxX, sd.StartPoint.X); minY = Math.Min(minY, sd.StartPoint.Y); maxY = Math.Max(maxY, sd.StartPoint.Y); minX = Math.Min(minX, sd.EndPoint.X); maxX = Math.Max(maxX, sd.EndPoint.X); minY = Math.Min(minY, sd.EndPoint.Y); maxY = Math.Max(maxY, sd.EndPoint.Y); } if (gf.FillType == FillType.Linear) { //<linearGradient id = "g1" x1 = "50%" y1 = "50%" x2 = "60%" y2 = "60%"> // <stop stop-color = "green" offset = "0%"/> // <stop stop-color = "pink" offset = "100%"/> //</linearGradient> xw.WriteStartElement("linearGradient"); xw.WriteStartAttribute("id"); xw.WriteValue("gf_" + gf.TagId); xw.WriteEndAttribute(); Matrix m = gf.Transform; Rectangle r = GradientFill.GradientVexRect; sysDraw2D.Matrix m2 = new sysDraw2D.Matrix(m.ScaleX, m.Rotate0, m.Rotate1, m.ScaleY, m.TranslateX, m.TranslateY); float midY = r.Point.Y + (r.Size.Height / 2); sysDraw.PointF pt0 = new sysDraw.PointF(r.Point.X, midY); sysDraw.PointF pt1 = new sysDraw.PointF(r.Point.X + r.Size.Width, midY); sysDraw.PointF[] pts = new sysDraw.PointF[] { pt0, pt1 }; m2.TransformPoints(pts); float ratX = 1 / (maxX - minX); float ratY = 1 / (maxY - minY); float d0x = (pts[0].X - minX) * ratX; float d0y = (pts[0].Y - minY) * ratY; float d1x = (pts[1].X - minX) * ratX; float d1y = (pts[1].Y - minY) * ratY; xw.WriteStartAttribute("x1"); xw.WriteFloat(d0x); xw.WriteEndAttribute(); xw.WriteStartAttribute("y1"); xw.WriteFloat(d0y); xw.WriteEndAttribute(); xw.WriteStartAttribute("x2"); xw.WriteFloat(d1x); xw.WriteEndAttribute(); xw.WriteStartAttribute("y2"); xw.WriteFloat(d1y); xw.WriteEndAttribute(); xw.WriteStartAttribute("spreadMethod"); xw.WriteValue("pad"); xw.WriteEndAttribute(); for (int i = 0; i < gf.Stops.Count; i++) { xw.WriteStartElement("stop"); xw.WriteStartAttribute("stop-color"); xw.WriteValue("#" + gf.Fills[i].RGB.ToString("X6")); xw.WriteEndAttribute(); if (gf.Fills[i].A < 255) { xw.WriteStartAttribute("stop-opacity"); xw.WriteValue((gf.Fills[i].A / 255f).ToString("f3")); xw.WriteEndAttribute(); } xw.WriteStartAttribute("offset"); xw.WriteFloat(gf.Stops[i] * 100); xw.WriteValue("%"); xw.WriteEndAttribute(); xw.WriteEndElement(); // stop } xw.WriteEndElement(); // linearGradient } else if (gf.FillType == FillType.Radial) { //<radialGradient id = "g2" cx = "100" cy = "100" r = "50"> // <stop stop-color = "green" offset = "0%"/> // <stop stop-color = "pink" offset = "100%"/> //</radialGradient> xw.WriteStartElement("radialGradient"); xw.WriteStartAttribute("id"); xw.WriteValue("gf_" + gf.TagId); xw.WriteEndAttribute(); xw.WriteAttributeString("gradientUnits", "userSpaceOnUse"); xw.WriteAttributeString("cx", "0"); xw.WriteAttributeString("cy", "0"); xw.WriteAttributeString("r", GradientFill.GradientVexRect.Right.ToString()); Matrix m = gf.Transform; xw.WriteStartAttribute("gradientTransform"); xw.WriteValue("matrix(" + m.ScaleX + "," + m.Rotate0 + "," + m.Rotate1 + "," + m.ScaleY + "," + m.TranslateX + "," + m.TranslateY + ")"); xw.WriteEndAttribute(); xw.WriteStartAttribute("spreadMethod"); xw.WriteValue("pad"); xw.WriteEndAttribute(); for (int i = gf.Stops.Count - 1; i >= 0; i--) { xw.WriteStartElement("stop"); xw.WriteStartAttribute("stop-color"); xw.WriteValue("#" + gf.Fills[i].RGB.ToString("X6")); xw.WriteEndAttribute(); if (gf.Fills[i].A < 255) { xw.WriteStartAttribute("stop-opacity"); xw.WriteValue((gf.Fills[i].A / 255f).ToString("f3")); xw.WriteEndAttribute(); } xw.WriteStartAttribute("offset"); xw.WriteFloat((1 - gf.Stops[i]) * 100); // xaml fill is reversed from gdi xw.WriteValue("%"); xw.WriteEndAttribute(); xw.WriteEndElement(); // stop } xw.WriteEndElement(); // radialGradient } }
// Update is called once per frame protected override void Update() { transform.position = CubicBezier.GetPoint(startPoint.Anchore, startPoint.Anchore + startPoint.Handle2, startPoint.Anchore + endPoint.Anchore + endPoint.Handle1, startPoint.Anchore + endPoint.Anchore, t); base.Update(); }
public CubicBezier GetNearestCurves(Vector3 point, out bool twoCurves, out CubicBezier curve2) { var idx = GetNearestControlPointIdx(point); return(GetCurvesFromControlPointIdx(idx, out twoCurves, out curve2)); }
public EaseBezier(Vector2 handle1, Vector2 handle2) { curve = new CubicBezier(handle1, handle2); }
public EaseBezier(CubicBezier curve) { this.curve = curve; }
public EffectParamF(float a, float b, CubicBezier curve) : base(a, b, (x, y, t) => curve.Sample(t) * (y - x) + x) { }
/// <summary> /// Attempts to find a slightly better parameterization for u on the given curve. /// </summary> protected void Reparameterize(int first, int last, CubicBezier curve) { List<VECTOR> pts = _pts; List<FLOAT> u = _u; int nPts = last - first; for (int i = 1; i < nPts; i++) { VECTOR p = pts[first + i]; FLOAT t = u[i]; FLOAT ti = 1 - t; // Control vertices for Q' VECTOR qp0 = (curve.p1 - curve.p0) * 3; VECTOR qp1 = (curve.p2 - curve.p1) * 3; VECTOR qp2 = (curve.p3 - curve.p2) * 3; // Control vertices for Q'' VECTOR qpp0 = (qp1 - qp0) * 2; VECTOR qpp1 = (qp2 - qp1) * 2; // Evaluate Q(t), Q'(t), and Q''(t) VECTOR p0 = curve.Sample(t); VECTOR p1 = ((ti * ti) * qp0) + ((2 * ti * t) * qp1) + ((t * t) * qp2); VECTOR p2 = (ti * qpp0) + (t * qpp1); // these are the actual fitting calculations using http://en.wikipedia.org/wiki/Newton%27s_method // We can't just use .X and .Y because Unity uses lower-case "x" and "y". FLOAT num = ((VectorHelper.GetX(p0) - VectorHelper.GetX(p)) * VectorHelper.GetX(p1)) + ((VectorHelper.GetY(p0) - VectorHelper.GetY(p)) * VectorHelper.GetY(p1)); FLOAT den = (VectorHelper.GetX(p1) * VectorHelper.GetX(p1)) + (VectorHelper.GetY(p1) * VectorHelper.GetY(p1)) + ((VectorHelper.GetX(p0) - VectorHelper.GetX(p)) * VectorHelper.GetX(p2)) + ((VectorHelper.GetY(p0) - VectorHelper.GetY(p)) * VectorHelper.GetY(p2)); FLOAT newU = t - num / den; if (Math.Abs(den) > EPSILON && newU >= 0 && newU <= 1) u[i] = newU; } }
public void BezierTest() { Game game = new Game(1024, 768, false, "Bezier test", 60); Scene scene = new Scene(); CubicBezier bez = new CubicBezier() { Position = new PointF(1024 / 2, 768 / 2), FillColor = Color.Red }; int handleDiameter = 6; Color handleColor = Color.Orange; Color handleLineColor = Color.DimGray; Ellipse handle0 = new Ellipse() { Position = bez.P0.Add(bez.Position), Width = handleDiameter, Height = handleDiameter, FillColor = handleColor }; handle0.Tag = new Action(() => bez.P0 = handle0.Position.Subtract(bez.Position)); Ellipse handle1 = new Ellipse() { Position = bez.P1.Add(bez.Position), Width = handleDiameter, Height = handleDiameter, FillColor = handleColor }; handle1.Tag = new Action(() => bez.P1 = handle1.Position.Subtract(bez.Position)); Ellipse handle2 = new Ellipse() { Position = bez.P2.Add(bez.Position), Width = handleDiameter, Height = handleDiameter, FillColor = handleColor }; handle2.Tag = new Action(() => bez.P2 = handle2.Position.Subtract(bez.Position)); Ellipse handle3 = new Ellipse() { Position = bez.P3.Add(bez.Position), Width = handleDiameter, Height = handleDiameter, FillColor = handleColor }; handle3.Tag = new Action(() => bez.P3 = handle3.Position.Subtract(bez.Position)); Line line01 = new Line() { Position = handle0.Position, End = handle1.Position, FillColor = handleLineColor, Tag = Tuple.Create(handle0, handle1) }; Line line12 = new Line() { Position = handle1.Position, End = handle2.Position, FillColor = handleLineColor, Tag = Tuple.Create(handle1, handle2) }; Line line23 = new Line() { Position = handle2.Position, End = handle3.Position, FillColor = handleLineColor, Tag = Tuple.Create(handle2, handle3) }; List <Ellipse> handles = new List <Ellipse>() { handle0, handle1, handle2, handle3 }; List <Line> lines = new List <Line>() { line01, line12, line23 }; scene.Add(line01, line12, line23); scene.Add(handle0, handle1, handle2, handle3); scene.Add(bez); Ellipse clickedOn = null; bool isLeftMouseDown = false; bool isRightMouseDown = false; game.MouseDown += args => { PointF mousePos = new PointF(args.X, 768 - args.Y); if (args.Button.Equals(MouseButton.Left)) { isLeftMouseDown = true; if (clickedOn == null) { foreach (Ellipse handle in handles) { if (handle.Contains(mousePos)) { clickedOn = handle; break; } } } } if (args.Button.Equals(MouseButton.Right)) { isRightMouseDown = true; } }; game.MouseUp += args => { if (args.Button.Equals(MouseButton.Left)) { isLeftMouseDown = false; clickedOn = null; } if (args.Button.Equals(MouseButton.Right)) { isRightMouseDown = false; } }; PointF lastMousePos = PointF.Empty; PointF mouseDelta = PointF.Empty; game.MouseMove += args => { PointF mousePos = new PointF(args.X, 768 - args.Y); mouseDelta = mousePos.Subtract(lastMousePos); if (isLeftMouseDown) { if (clickedOn != null) { clickedOn.Position = clickedOn.Position.Add(mouseDelta); ((Action)clickedOn.Tag)(); } } else if (isRightMouseDown) { bez.Position = bez.Position.Add(mouseDelta); handles.ForEach(h => h.Position = h.Position.Add(mouseDelta)); } lastMousePos = mousePos; }; scene.Update += args => { foreach (Line line in lines) { Tuple <Ellipse, Ellipse> points = (Tuple <Ellipse, Ellipse>)line.Tag; line.Position = points.Item1.Position; line.End = points.Item2.Position; } }; game.ActiveScene = scene; game.Start(); }
void SimplifyPaths() { //return; //-------- //lets smooth it //string str1 = dbugDumpPointsToString(contPoints); //string str2 = dbugDumpPointsToString2(contPoints); //var data2 = CurvePreprocess.RdpReduce(contPoints, 2); List <Vector2> data2 = contPoints; CubicBezier[] cubicBzs = CurveFit.Fit(data2, 8); vxs = new VertexStore(); int j = cubicBzs.Length; //1. if (j > 1) { //1st CubicBezier bz0 = cubicBzs[0]; vxs.AddMoveTo(bz0.p0.x, bz0.p0.y); vxs.AddLineTo(bz0.p0.x, bz0.p0.y); if (!bz0.HasSomeNanComponent) { vxs.AddCurve4To( bz0.p1.x, bz0.p1.y, bz0.p2.x, bz0.p2.y, bz0.p3.x, bz0.p3.y); } else { vxs.AddLineTo(bz0.p3.x, bz0.p3.y); } //------------------------------- for (int i = 1; i < j; ++i) //start at 1 { CubicBezier bz = cubicBzs[i]; if (!bz.HasSomeNanComponent) { vxs.AddCurve4To( bz.p1.x, bz.p1.y, bz.p2.x, bz.p2.y, bz.p3.x, bz.p3.y); } else { vxs.AddLineTo(bz0.p3.x, bz0.p3.y); } } //------------------------------- //close //TODO: we not need this AddLineTo() vxs.AddLineTo(bz0.p0.x, bz0.p0.y); vxs.AddCloseFigure(); } else if (j == 1) { CubicBezier bz0 = cubicBzs[0]; vxs.AddMoveTo(bz0.p0.x, bz0.p0.y); if (!bz0.HasSomeNanComponent) { vxs.AddCurve4To( bz0.p1.x, bz0.p1.y, bz0.p2.x, bz0.p2.y, bz0.p3.x, bz0.p3.y); } else { vxs.AddLineTo(bz0.p3.x, bz0.p3.y); } } else { // = 0 } //TODO: review here VertexStore v2 = new VertexStore(); cflat.MakeVxs(vxs, v2); vxs = v2; }
public BezierPathSegment(Coordinates p0, Coordinates p1, Coordinates p2, Coordinates p3, double?endSpeed, bool stopLine) { cb = new CubicBezier(p0, p1, p2, p3); this.endSpeed = endSpeed; this.stopLine = stopLine; }
public static string GetShapeClass(Size canvasSize, NShape nshape) { StringBuilder sb = new StringBuilder(); if (nshape != null) { sb.AppendLine("using System.Collections.Generic;"); sb.AppendLine("using System.Drawing;"); sb.AppendLine("using Dataweb.NShape;"); sb.AppendLine("using Dataweb.NShape.Advanced;"); sb.AppendLine(""); sb.AppendLine("namespace " + nshape.Namespace); sb.AppendLine("{"); sb.AppendLine(""); sb.AppendLine(tab1 + "public class " + nshape.ClassName + " : RectangleFBase"); sb.AppendLine(tab1 + "{"); sb.AppendLine(""); sb.AppendLine(tab2 + "public enum MemberShape"); sb.AppendLine(tab2 + "{"); for (int i1 = 0; i1 < nshape.Paths.Count; i1++) { sb.Append(tab3 + nshape.Paths[i1].Name); if (i1 != nshape.Paths.Count - 1) { sb.AppendLine(","); } else { sb.AppendLine(""); } } sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "private MemberShape _member;"); sb.AppendLine(tab2 + "public MemberShape Member"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "get"); sb.AppendLine(tab3 + "{"); sb.AppendLine(tab4 + "return _member;"); sb.AppendLine(tab3 + "}"); sb.AppendLine(tab3 + "set"); sb.AppendLine(tab3 + "{"); sb.AppendLine(tab4 + "if (_member != value)"); sb.AppendLine(tab4 + "{"); sb.AppendLine(tab5 + "_member = value;"); sb.AppendLine(tab5 + "Invalidate();"); sb.AppendLine(tab5 + "InvalidateDrawCache();"); sb.AppendLine(tab4 + "}"); sb.AppendLine(tab3 + "}"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "#region Constructors"); sb.AppendLine(""); sb.AppendLine(tab2 + "protected internal " + nshape.ClassName + "(ShapeType shapeType, Template template)"); sb.AppendLine(tab3 + ": base(shapeType, template)"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "WidthF = " + nshape.Paths[0].WidthF + "F;"); sb.AppendLine(tab3 + "HeightF = " + nshape.Paths[0].HeightF + "F;"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "protected internal " + nshape.ClassName + "(ShapeType shapeType, IStyleSet styleSet)"); sb.AppendLine(tab3 + ": base(shapeType, styleSet)"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "WidthF = " + nshape.Paths[0].WidthF + "F;"); sb.AppendLine(tab3 + "HeightF = " + nshape.Paths[0].HeightF + "F;"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "#endregion Constructors"); sb.AppendLine(""); sb.AppendLine(tab2 + "#region Required Methods"); sb.AppendLine(""); sb.AppendLine(tab2 + "public override Shape Clone()"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "Shape result = new " + nshape.ClassName + "(Type, Template);"); sb.AppendLine(tab3 + "result.CopyFrom(this);"); sb.AppendLine(tab3 + "return result;"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "protected override bool CalculatePath()"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "if (base.CalculatePath())"); sb.AppendLine(tab3 + "{"); sb.AppendLine(tab4 + "Path.Reset();"); sb.AppendLine(tab4 + "switch (Member)"); sb.AppendLine(tab4 + "{"); for (int i1 = 0; i1 < nshape.Paths.Count; i1++) { sb.AppendLine(tab5 + "case MemberShape." + nshape.Paths[i1].Name + ":"); sb.AppendLine(tab6 + nshape.Paths[i1].Name + "Path();"); sb.AppendLine(tab6 + "break;"); } sb.AppendLine(tab4 + "}"); sb.AppendLine(tab4 + "return true;"); sb.AppendLine(tab3 + "}"); sb.AppendLine(tab3 + "return false;"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); for (int i1 = 0; i1 < nshape.Paths.Count; i1++) { sb.AppendLine(tab2 + "private void " + nshape.Paths[i1].Name + "Path()"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "WidthF = " + nshape.Paths[i1].WidthF + "F;"); sb.AppendLine(tab3 + "HeightF = " + nshape.Paths[i1].HeightF + "F;"); for (int i2 = 0; i2 < nshape.Paths[i1].Segments.Count; i2++) { if (nshape.Paths[i1].Segments[i2].IsValidPathSegment) { if (nshape.Paths[i1].Segments[i2].StartFigure) { sb.AppendLine(tab3 + "Path.StartFigure();"); } switch (nshape.Paths[i1].Segments[i2].SegmentType) { case GDIPathSegmentTypeName.Arc: Arc arc = (Arc)nshape.Paths[i1].Segments[i2]; if (arc.StartAngle > 180) { arc.StartAngle -= 180; } else { arc.StartAngle += 180; } sb.AppendLine(tab3 + "Path.AddArc(" + arc.X + "F * Scale * _pixelToMmMultiple, " + arc.Y + "F * -1 * Scale * _pixelToMmMultiple, " + arc.Width + "F * Scale * _pixelToMmMultiple, " + arc.Height + "F * Scale * _pixelToMmMultiple, " + arc.StartAngle + "F, " + arc.SweepAngle + "F);"); break; case GDIPathSegmentTypeName.CubicBezier: CubicBezier cub = (CubicBezier)nshape.Paths[i1].Segments[i2]; sb.AppendLine(tab3 + "Path.AddBezier(" + cub.StartingPointX + "F * Scale * _pixelToMmMultiple, " + cub.StartingPointY + "F * -1 * Scale * _pixelToMmMultiple, " + cub.ControlPointOneX + "F * Scale * _pixelToMmMultiple, " + cub.ControlPointOneY + "F * -1 * Scale * _pixelToMmMultiple, " + cub.ControlPointTwoX + "F * Scale * _pixelToMmMultiple, " + cub.ControlPointTwoY + "F * -1 * Scale * _pixelToMmMultiple, " + cub.EndingPointX + "F * Scale * _pixelToMmMultiple, " + cub.EndingPointY + "F * -1 * Scale * _pixelToMmMultiple);"); break; case GDIPathSegmentTypeName.Lines: Lines lin = (Lines)nshape.Paths[i1].Segments[i2]; sb.Append(tab3 + "Path.AddLines(new PointF[]{"); for (int p = 0; p < lin.Points.Length; p++) { sb.Append("new PointF(" + lin.Points[p].X + "F * Scale * _pixelToMmMultiple, " + lin.Points[p].Y + "F * -1 * Scale * _pixelToMmMultiple)"); if (p + 1 < lin.Points.Length) { sb.Append(", "); } } sb.AppendLine("});"); break; case GDIPathSegmentTypeName.Polygon: Polygon pol = (Polygon)nshape.Paths[i1].Segments[i2]; sb.AppendLine(tab3 + "Path.AddPolygon(new PointF[]"); sb.AppendLine(tab3 + "{"); for (int p = 0; p < pol.Points.Length; p++) { sb.Append(tab5 + "new PointF(" + pol.Points[p].X + "F * Scale * _pixelToMmMultiple, " + pol.Points[p].Y + "F * -1 * Scale * _pixelToMmMultiple)"); if ((p + 1) < pol.Points.Length) { sb.Append(", "); } sb.AppendLine(); } sb.AppendLine(tab3 + "});"); break; case GDIPathSegmentTypeName.Rectangle: NShapeCreator.Rectangle rec = (NShapeCreator.Rectangle)nshape.Paths[i1].Segments[i2]; sb.AppendLine(tab3 + "Path.AddRectangle(new RectangleF(" + rec.X + "F * Scale * _pixelToMmMultiple, " + rec.Y + "F * -1 * Scale * _pixelToMmMultiple, " + rec.Width + "F * Scale * _pixelToMmMultiple, " + rec.Height + "F * Scale * _pixelToMmMultiple));"); break; } if (nshape.Paths[i1].Segments[i2].CloseFigure) { sb.AppendLine(tab3 + "Path.CloseFigure();"); } } } sb.AppendLine(tab2 + "}"); sb.AppendLine(""); } sb.AppendLine(tab2 + "public static ShapeType GetShapeType()"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "string libraryName = \"" + nshape.LibraryName + "\";"); sb.AppendLine(tab3 + "return new ShapeType(\"" + nshape.ClassName + "\", libraryName, libraryName,"); sb.AppendLine(tab5 + "delegate(ShapeType s, Template t) { return new " + nshape.ClassName + "(s, t); },"); sb.AppendLine(tab3 + nshape.ClassName + ".GetPropertyDefinitions, " + nshape.Namespace + ".Properties.Resources." + nshape.ClassName + ");"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "protected override void InitializeToDefault(IStyleSet styleSet)"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "base.InitializeToDefault(styleSet);"); sb.AppendLine(tab3 + "WidthF = " + nshape.Paths[0].WidthF + "F;"); sb.AppendLine(tab3 + "HeightF = " + nshape.Paths[0].HeightF + "F;"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "#endregion Required Methods"); sb.AppendLine(""); sb.AppendLine(tab2 + "#region ControlPoints"); sb.AppendLine(""); sb.AppendLine(tab2 + "#region Required Sub-Class"); sb.AppendLine(""); sb.AppendLine(tab2 + "new public class ControlPointIds"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "public const int Reference = ControlPointId.Reference;"); sb.AppendLine(tab3 + "public const int MiddleCenter = 1;"); sb.AppendLine(tab3 + "public const int " + nshape.ClassName + "MiddleCenter = 2;"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "#endregion Required Sub-Class"); sb.AppendLine(""); sb.AppendLine(tab2 + "protected override void CalcControlPoints()"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "ControlPoints[ControlPointIds.Reference] = Point.Empty;"); sb.AppendLine(tab3 + "ControlPoints[ControlPointIds.MiddleCenter] = Point.Empty;"); sb.AppendLine(tab3 + "ControlPoints[ControlPointIds." + nshape.ClassName + "MiddleCenter] = Point.Empty;"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "public override IEnumerable<ControlPointId> GetControlPointIds(ControlPointCapabilities controlPointCapability)"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "List<ControlPointId> returnValue = new List<ControlPointId>();"); sb.AppendLine(tab3 + "if ((controlPointCapability & ControlPointCapabilities.Rotate) != 0)"); sb.AppendLine(tab3 + "{"); sb.AppendLine(tab4 + "returnValue.Add(ControlPointIds.MiddleCenter);"); sb.AppendLine(tab4 + "returnValue.Add(ControlPointIds.Reference);"); sb.AppendLine(tab3 + "}"); sb.AppendLine(tab3 + "if ((controlPointCapability & ControlPointCapabilities.Connect) != 0)"); sb.AppendLine(tab3 + "{"); sb.AppendLine(tab4 + "returnValue.Add(ControlPointIds." + nshape.ClassName + "MiddleCenter);"); sb.AppendLine(tab3 + "}"); sb.AppendLine(tab3 + "return returnValue;"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "public override Point GetControlPointPosition(ControlPointId controlPointId)"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "return ControlPoints[controlPointId];"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "public override bool HasControlPointCapability(ControlPointId controlPointId, ControlPointCapabilities controlPointCapability)"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "bool returnValue = false;"); sb.AppendLine(tab3 + "switch (controlPointId)"); sb.AppendLine(tab3 + "{"); sb.AppendLine(tab4 + "case ControlPointIds.MiddleCenter:"); sb.AppendLine(tab4 + "case ControlPointId.Reference:"); sb.AppendLine(tab5 + "returnValue = (controlPointCapability & ControlPointCapabilities.Rotate) != 0;"); sb.AppendLine(tab5 + "break;"); sb.AppendLine(tab4 + "case ControlPointIds." + nshape.ClassName + "MiddleCenter:"); sb.AppendLine(tab5 + "returnValue = (controlPointCapability & ControlPointCapabilities.Connect) != 0;"); sb.AppendLine(tab5 + "break;"); sb.AppendLine(tab3 + "}"); sb.AppendLine(tab3 + "return returnValue;"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "private const int _controlPointCount = 3;"); sb.AppendLine(tab2 + "protected override int ControlPointCount"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "get"); sb.AppendLine(tab3 + "{"); sb.AppendLine(tab4 + "return _controlPointCount;"); sb.AppendLine(tab3 + "}"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "#endregion ControlPoints"); sb.AppendLine(""); for (int i1 = 0; i1 < nshape.Properties.Count; i1++) { sb.AppendLine(tab2 + "public " + nshape.Properties[i1].Type + " " + nshape.Properties[i1].Name); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "get;set;"); sb.AppendLine(tab2 + "}"); sb.AppendLine(""); } sb.AppendLine(tab2 + "new public static IEnumerable<EntityPropertyDefinition> GetPropertyDefinitions(int version)"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "foreach (EntityPropertyDefinition pi in RectangleFBase.GetPropertyDefinitions(version))"); sb.AppendLine(tab3 + "{"); sb.AppendLine(tab4 + "yield return pi;"); sb.AppendLine(tab3 + "}"); for (int i1 = 0; i1 < nshape.Properties.Count; i1++) { sb.AppendLine(tab3 + "yield return new EntityFieldDefinition(\"" + nshape.Properties[i1].Name + "\", typeof(" + nshape.Properties[i1].Type + "));"); } sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "protected override void LoadFieldsCore(IRepositoryReader reader, int version)"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "base.LoadFieldsCore(reader, version);"); for (int i1 = 0; i1 < nshape.Properties.Count; i1++) { sb.AppendLine(tab3 + nshape.Properties[i1].Name + " = reader.Read" + nshape.Properties[i1].Type + "();"); } sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab2 + "protected override void SaveFieldsCore(IRepositoryWriter writer, int version)"); sb.AppendLine(tab2 + "{"); sb.AppendLine(tab3 + "base.SaveFieldsCore(writer, version);"); for (int i1 = 0; i1 < nshape.Properties.Count; i1++) { sb.AppendLine(tab3 + "writer.Write" + nshape.Properties[i1].Type + "(" + nshape.Properties[i1].Name + ");"); } sb.AppendLine(tab2 + "}"); sb.AppendLine(""); sb.AppendLine(tab1 + "}"); sb.Append("}"); } return(sb.ToString()); }
public void Bezier(CubicBezier bezier) { record(t => t.Bezier(bezier)); }
private void WritePath(DrawPath path) { int count = 0; List <SegmentType> types = new List <SegmentType>(); List <int> values = new List <int>(); Point prevPoint = Point.Empty; for (int i = 0; i < path.Segments.Count; i++) { IShapeData sd = path.Segments[i]; // moveTo if (sd.StartPoint != prevPoint) { types.Add(SegmentType.Move); values.Add((int)(sd.StartPoint.X * DrawObject.twips)); values.Add((int)(sd.StartPoint.Y * DrawObject.twips)); count += 2; } types.Add(sd.SegmentType); switch (sd.SegmentType) { case SegmentType.Line: values.Add((int)(sd.EndPoint.X * DrawObject.twips)); values.Add((int)(sd.EndPoint.Y * DrawObject.twips)); count += 2; break; case SegmentType.QuadraticBezier: QuadBezier qb = (QuadBezier)sd; values.Add((int)(qb.Control.X * DrawObject.twips)); values.Add((int)(qb.Control.Y * DrawObject.twips)); values.Add((int)(qb.EndPoint.X * DrawObject.twips)); values.Add((int)(qb.EndPoint.Y * DrawObject.twips)); count += 4; break; case SegmentType.CubicBezier: CubicBezier cb = (CubicBezier)sd; values.Add((int)(cb.Control0.X * DrawObject.twips)); values.Add((int)(cb.Control0.Y * DrawObject.twips)); values.Add((int)(cb.Control1.X * DrawObject.twips)); values.Add((int)(cb.Control1.Y * DrawObject.twips)); values.Add((int)(cb.EndPoint.X * DrawObject.twips)); values.Add((int)(cb.EndPoint.Y * DrawObject.twips)); count += 6; break; } prevPoint = sd.EndPoint; } uint dataBits = MinBits(values); WriteNBitsCount(dataBits); WriteBits(types.Count, 11); int[] lens = new int[] { 2, 2, 4, 6 }; int valIndex = 0; for (int i = 0; i < types.Count; i++) { // types M:0 L:1 Q:2 C:3 int type = (int)types[i]; WriteBits(type, 2); // data for (int j = 0; j < lens[type]; j++) { WriteBits(values[valIndex++], dataBits); } } }
public bool Equals(CubicBezier other) { return Start.Equals(other.Start) && Span1.Equals(other.Span1) && Span2.Equals(other.Span2) && End.Equals(other.End); }
public BezierPathSegment(CubicBezier bezier, double?endSpeed, bool stopLine) { cb = bezier; this.endSpeed = endSpeed; this.stopLine = stopLine; }
internal void Interpolate( ActorPatch finalFrame, string animationName, float duration, float[] curve, bool enabled) { // Ensure duration is in range [0...n]. duration = Math.Max(0, duration); const int FPS = 10; float timeStep = duration / FPS; // If the curve is malformed, fall back to linear. if (curve.Length != 4) { curve = new float[] { 0, 0, 1, 1 }; } // Are we patching the transform? bool animateTransform = finalFrame.Transform != null && finalFrame.Transform.Local != null && finalFrame.Transform.Local.IsPatched(); var finalTransform = finalFrame.Transform.Local; // What parts of the transform are we animating? bool animatePosition = animateTransform && finalTransform.Position != null && finalTransform.Position.IsPatched(); bool animateRotation = animateTransform && finalTransform.Rotation != null && finalTransform.Rotation.IsPatched(); bool animateScale = animateTransform && finalTransform.Scale != null && finalTransform.Scale.IsPatched(); // Ensure we have a well-formed rotation quaternion. for (; animateRotation;) { var rotation = finalTransform.Rotation; bool hasAllComponents = rotation.X.HasValue && rotation.Y.HasValue && rotation.Z.HasValue && rotation.W.HasValue; // If quaternion is incomplete, fall back to the identity. if (!hasAllComponents) { finalTransform.Rotation = new QuaternionPatch(Quaternion.identity); break; } // Ensure the quaternion is normalized. var lengthSquared = (rotation.X.Value * rotation.X.Value) + (rotation.Y.Value * rotation.Y.Value) + (rotation.Z.Value * rotation.Z.Value) + (rotation.W.Value * rotation.W.Value); if (lengthSquared == 0) { // If the quaternion is length zero, fall back to the identity. finalTransform.Rotation = new QuaternionPatch(Quaternion.identity); break; } else if (lengthSquared != 1.0f) { // If the quaternion length is not 1, normalize it. var inverseLength = 1.0f / Mathf.Sqrt(lengthSquared); rotation.X *= inverseLength; rotation.Y *= inverseLength; rotation.Z *= inverseLength; rotation.W *= inverseLength; } break; } // Create the sampler to calculate ease curve values. var sampler = new CubicBezier(curve[0], curve[1], curve[2], curve[3]); var keyframes = new List <MWAnimationKeyframe>(); // Generate keyframes float currTime = 0; do { var keyframe = NewKeyframe(currTime); var unitTime = duration > 0 ? currTime / duration : 1; BuildKeyframe(keyframe, unitTime); keyframes.Add(keyframe); currTime += timeStep; }while (currTime <= duration && timeStep > 0); // Final frame (if needed) if (currTime - duration > 0) { var keyframe = NewKeyframe(duration); BuildKeyframe(keyframe, 1); keyframes.Add(keyframe); } // Create and optionally start the animation. CreateAnimation( animationName, keyframes, events: null, wrapMode: MWAnimationWrapMode.Once, initialState: new MWSetAnimationStateOptions { Enabled = enabled }, isInternal: true, onCreatedCallback: null); bool LerpFloat(out float dest, float start, float?end, float t) { if (end.HasValue) { dest = Mathf.LerpUnclamped(start, end.Value, t); return(true); } dest = 0; return(false); } bool SlerpQuaternion(out Quaternion dest, Quaternion start, QuaternionPatch end, float t) { if (end != null) { dest = Quaternion.SlerpUnclamped(start, new Quaternion(end.X.Value, end.Y.Value, end.Z.Value, end.W.Value), t); return(true); } dest = Quaternion.identity; return(false); } void BuildKeyframePosition(MWAnimationKeyframe keyframe, float t) { float value; if (LerpFloat(out value, transform.localPosition.x, finalTransform.Position.X, t)) { keyframe.Value.Transform.Local.Position.X = value; } if (LerpFloat(out value, transform.localPosition.y, finalTransform.Position.Y, t)) { keyframe.Value.Transform.Local.Position.Y = value; } if (LerpFloat(out value, transform.localPosition.z, finalTransform.Position.Z, t)) { keyframe.Value.Transform.Local.Position.Z = value; } } void BuildKeyframeScale(MWAnimationKeyframe keyframe, float t) { float value; if (LerpFloat(out value, transform.localScale.x, finalTransform.Scale.X, t)) { keyframe.Value.Transform.Local.Scale.X = value; } if (LerpFloat(out value, transform.localScale.y, finalTransform.Scale.Y, t)) { keyframe.Value.Transform.Local.Scale.Y = value; } if (LerpFloat(out value, transform.localScale.z, finalTransform.Scale.Z, t)) { keyframe.Value.Transform.Local.Scale.Z = value; } } void BuildKeyframeRotation(MWAnimationKeyframe keyframe, float t) { Quaternion value; if (SlerpQuaternion(out value, transform.localRotation, finalTransform.Rotation, t)) { keyframe.Value.Transform.Local.Rotation = new QuaternionPatch(value); } } void BuildKeyframe(MWAnimationKeyframe keyframe, float unitTime) { float curveTime = sampler.Sample(unitTime); if (animatePosition) { BuildKeyframePosition(keyframe, curveTime); } if (animateRotation) { BuildKeyframeRotation(keyframe, curveTime); } if (animateScale) { BuildKeyframeScale(keyframe, curveTime); } } MWAnimationKeyframe NewKeyframe(float time) { var keyframe = new MWAnimationKeyframe { Time = time, Value = new ActorPatch() }; if (animateTransform) { keyframe.Value.Transform = new ActorTransformPatch() { Local = new ScaledTransformPatch() }; } if (animatePosition) { keyframe.Value.Transform.Local.Position = new Vector3Patch(); } if (animateRotation) { keyframe.Value.Transform.Local.Rotation = new QuaternionPatch(); } if (animateScale) { keyframe.Value.Transform.Local.Scale = new Vector3Patch(); } return(keyframe); } }
public void Slam(Vector3 target) { if (hasTarget) return; targetMode = TargetMode.SLAM; Vector3 start = transform.position; start.x = Mathf.Clamp(start.x, transform.parent.position.x + minX, transform.parent.position.x + maxX); Vector3 end = target; end.x = Mathf.Clamp(end.x, transform.parent.position.x + minX, transform.parent.position.x + maxX); end.y = start.y; Vector3 b = new Vector3(start.x, start.y + maxHeight * 0.5f); Vector3 c = new Vector3(end.x, start.y + maxHeight); Vector3[] points = new Vector3[] { start, b, c, end }; bezier = new CubicBezier(points); hasTarget = true; progress = 0.01f; }
public BezierPathSegment(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, double?endSpeed, bool stopLine) { cb = new CubicBezier(p0, p1, p2, p3); this.endSpeed = endSpeed; this.stopLine = stopLine; }