예제 #1
0
 /// <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;
     }
 }
예제 #2
0
 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);
			}
		}
예제 #6
0
        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;
        }
예제 #7
0
 public void Awake()
 {
     cubicBezier = target as CubicBezier;
 }
예제 #8
0
        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]);
 }
예제 #10
0
        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)));
                }
            }
        }
예제 #11
0
        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;
        }
예제 #12
0
        /// <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;
        }
예제 #13
0
        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}");
                }
            }
        }
예제 #14
0
 public EffectParamI(int a, int b, CubicBezier curve)
     : base(a, b, (x, y, t) => (int)(curve.Sample(t) * (y - x)) + x)
 {
 }
예제 #15
0
        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
        }
예제 #16
0
        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
            }
        }
예제 #17
0
 // 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();
 }
예제 #18
0
        public CubicBezier GetNearestCurves(Vector3 point, out bool twoCurves, out CubicBezier curve2)
        {
            var idx = GetNearestControlPointIdx(point);

            return(GetCurvesFromControlPointIdx(idx, out twoCurves, out curve2));
        }
예제 #19
0
 public EaseBezier(Vector2 handle1, Vector2 handle2)
 {
     curve = new CubicBezier(handle1, handle2);
 }
예제 #20
0
 public EaseBezier(CubicBezier curve)
 {
     this.curve = curve;
 }
예제 #21
0
 public EffectParamF(float a, float b, CubicBezier curve)
     : base(a, b, (x, y, t) => curve.Sample(t) * (y - x) + x)
 {
 }
예제 #22
0
 /// <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;
     }
 }
예제 #23
0
파일: SimpleTests.cs 프로젝트: deblob/GaLi
        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();
        }
예제 #24
0
        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;
 }
예제 #26
0
        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());
        }
예제 #27
0
 public void Bezier(CubicBezier bezier)
 {
     record(t => t.Bezier(bezier));
 }
예제 #28
0
        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);
                }
            }
        }
예제 #29
0
 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);
            }
        }
예제 #32
0
    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;
    }
예제 #33
0
 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;
 }