Beispiel #1
0
 /// <summary>
 /// ベジエ曲線の長さを得る
 /// </summary>
 /// <param name="bcp1">一つ目のベジエ頂点</param>
 /// <param name="bcp2">二つ目のベジエ頂点</param>
 /// <returns></returns>
 public static float GetBezeierLength(BezierControlPoint bcp1, BezierControlPoint bcp2)
 {
     if (bcp1.ValidThird)
     {
         if (!bcp2.ValidFirst)
         {
             //second bezier
             return(GetBezeierLength(bcp1.Second, bcp1.Third, bcp2.Second, bcp2.Second));
         }
         else
         {
             //third bezier
             return(GetBezeierLength(bcp1.Second, bcp1.Third, bcp2.First, bcp2.Second));
         }
     }
     else
     {
         if (!bcp2.ValidFirst)
         {
             //first bezier
             return(GetLength(new PointF(bcp1.Second.X - bcp2.Second.X, bcp1.Second.Y - bcp2.Second.Y)));
         }
         else
         {
             //second bezier
             return(GetBezeierLength(bcp1.Second, bcp1.Second, bcp2.First, bcp2.Second));
         }
     }
 }
Beispiel #2
0
        /// <summary>
        /// 指定された割合分割されたベジエを得るメソッド
        /// </summary>
        /// <param name="num">最大、最小はMaxRatio,MinRatioから</param>
        /// <param name="bcps1">分割1</param>
        /// <param name="bcps2">分割2</param>
        public void GetDevidedBeziers(float num, out BezierControlPoint[] bcps1, out BezierControlPoint[] bcps2)
        {
            bcps1 = null;
            bcps2 = null;
            if (bcps == null || bcps.Length == 0)
            {
                return;
            }
            if (num < MinRatio)
            {
                num = MinRatio;
            }
            else if (num > MaxRatio)
            {
                num = MaxRatio;
            }
            //find where
            float sumnum = 0;
            float rest = 0;
            BezierControlPoint previous = null, next = null;
            int foundindex = -1;

            for (int i = 0; i < bcps.Length; i++)
            {
                BezierControlPoint bcp = bcps[i];
                if (previous != null)
                {
                    float ratio = eachlength[i - 1] / length * MaxRatio;
                    if (sumnum + ratio >= num || (sumnum + ratio) >= MaxRatio - 0.0009765625)
                    {
                        next       = bcp;
                        rest       = num - sumnum;
                        foundindex = i;
                        break;
                    }
                    sumnum += ratio;
                }
                previous = bcp;
            }
            if (foundindex != -1)
            {
                float targetratio = 1 - rest / MaxRatio * length / eachlength[foundindex - 1];
                BezierCaliculate.GetDevidedBeziers(previous, next, targetratio, out BezierControlPoint bcp1, out BezierControlPoint bcp2, out BezierControlPoint bcp3);
                bcps1 = new BezierControlPoint[foundindex + 1];
                bcps2 = new BezierControlPoint[BCPS.Length - foundindex + 1];
                for (int i = 0; i < foundindex - 1; i++)
                {
                    bcps1[i] = BCPS[i].Clone();
                }
                bcps1[foundindex - 1] = bcp1;
                bcps1[foundindex]     = bcp2.Clone();
                bcps2[0] = bcp2;
                bcps2[1] = bcp3;
                for (int i = foundindex + 1; i < BCPS.Length; i++)
                {
                    bcps2[i - foundindex + 1] = BCPS[i].Clone();
                }
                return;
            }
        }
Beispiel #3
0
        private void Analyze()
        {
            eachlength = new float[bcps.Length - 1];
            BezierControlPoint previous = null;

            for (int i = 0; i < bcps.Length; i++)
            {
                BezierControlPoint bcp = bcps[i];
                if (previous != null)
                {
                    eachlength[i - 1] += BezierCaliculate.GetBezeierLength(previous, bcp);
                    length            += eachlength[i - 1];
                }
                previous = bcp;
            }
        }
Beispiel #4
0
        /// <summary>
        /// クローンメソッド
        /// </summary>
        /// <returns></returns>
        public BezierControlPoint Clone()
        {
            var bcp = new BezierControlPoint
            {
                FirstDirection = FirstDirection,
                FirstLength    = FirstLength,
                Second         = Second,
                ThirdDirection = ThirdDirection,
                ThirdLength    = ThirdLength,
                ValidFirst     = ValidFirst,
                ValidSecond    = ValidSecond,
                ValidThird     = ValidThird
            };

            return(bcp);
        }
Beispiel #5
0
        /// <summary>
        /// 連結ベジエから特定の割合の場所を得るメソッド
        /// </summary>
        /// <param name="num">最大、最小はMaxRatio,MinRatioから</param>
        /// <param name="direction">位置</param>
        /// <param name="pos">向き</param>
        /// <returns></returns>
        public void GetPoint(float num, out PointF pos, out PointF direction)
        {
            pos       = PointF.Empty;
            direction = new PointF(1, 0);
            if (bcps == null || bcps.Length == 0)
            {
                return;
            }
            if (num < MinRatio)
            {
                num = MinRatio;
            }
            else if (num > MaxRatio)
            {
                num = MaxRatio;
            }
            //find where
            float sumnum = 0;
            float rest = 0;
            BezierControlPoint previous = null, next = null;
            int foundindex = -1;

            for (int i = 0; i < bcps.Length; i++)
            {
                BezierControlPoint bcp = bcps[i];
                if (previous != null)
                {
                    float ratio = eachlength[i - 1] / length * MaxRatio;
                    if (sumnum + ratio >= num || (sumnum + ratio) >= MaxRatio - 0.0009765625)
                    {
                        next       = bcp;
                        rest       = num - sumnum;
                        foundindex = i;
                        break;
                    }
                    sumnum += ratio;
                }
                previous = bcp;
            }
            if (foundindex != -1)
            {
                float targetlength = length * rest / MaxRatio;
                BezierCaliculate.GetBezeirSplitPoint(previous, next, targetlength, out pos, out direction);
                return;
            }
        }
Beispiel #6
0
        /// <summary>
        /// 分割されたベジエを得る
        /// </summary>
        /// <param name="bcp1">ベジエ頂点1</param>
        /// <param name="bcp2">ベジエ頂点2</param>
        /// <param name="t">割合(0~1)</param>
        /// <param name="obcp1">出力ベジエ頂点1</param>
        /// <param name="obcp2">出力ベジエ頂点2</param>
        /// <param name="obcp3">出力ベジエ頂点3</param>
        public static void GetDevidedBeziers(BezierControlPoint bcp1, BezierControlPoint bcp2, float t, out BezierControlPoint obcp1, out BezierControlPoint obcp2, out BezierControlPoint obcp3)
        {
            PointF p1, p2, p3, p4;

            p1 = bcp1.Second;
            if (bcp1.ValidThird)
            {
                p2 = bcp1.Third;
            }
            else
            {
                p2 = bcp1.Second;
            }
            if (bcp2.ValidFirst)
            {
                p3 = bcp2.First;
            }
            else
            {
                p3 = bcp2.Second;
            }
            p4 = bcp2.Second;
            GetFivePoint(p1, p2, p3, p4, out PointF outp1, out PointF outp2, out PointF outp3, out PointF outp4, out PointF outp5, t);
            obcp1 = bcp1.Clone();
            obcp2 = new BezierControlPoint();
            obcp3 = bcp2.Clone();
            if (obcp1.ValidThird)
            {
                obcp1.Third = outp1;
            }
            obcp2.Second     = outp3;
            obcp2.First      = outp2;
            obcp2.Third      = outp4;
            obcp2.ValidFirst = true;
            obcp2.ValidThird = true;
            if (obcp3.ValidFirst)
            {
                obcp3.First = outp5;
            }
        }
Beispiel #7
0
 /// <summary>
 /// ベジエ曲線を囲む部分を得る
 /// </summary>
 /// <param name="bcp1">ベジエ頂点1</param>
 /// <param name="bcp2">ベジエ頂点2</param>
 /// <param name="minx">最小のx</param>
 /// <param name="maxx">最大のx</param>
 /// <param name="miny">最小のy</param>
 /// <param name="maxy">最大のy</param>
 public static void GetArea(BezierControlPoint bcp1, BezierControlPoint bcp2, out float minx, out float maxx, out float miny, out float maxy)
 {
     if (bcp1.ValidThird)
     {
         if (!bcp2.ValidFirst)
         {
             //second bezier
             GetArea(bcp1.Second, bcp1.Third, bcp2.Second, bcp2.Second, out minx, out maxx, out miny, out maxy);
             return;
         }
         else
         {
             //third bezier
             GetArea(bcp1.Second, bcp1.Third, bcp2.First, bcp2.Second, out minx, out maxx, out miny, out maxy);
             return;
         }
     }
     else
     {
         if (!bcp2.ValidFirst)
         {
             //first bezier
             maxx = Math.Max(bcp1.Second.X, bcp2.Second.X);
             minx = Math.Min(bcp1.Second.X, bcp2.Second.X);
             maxy = Math.Max(bcp1.Second.Y, bcp2.Second.Y);
             miny = Math.Min(bcp1.Second.Y, bcp2.Second.Y);
             return;
         }
         else
         {
             //second bezier
             GetArea(bcp1.Second, bcp1.Second, bcp2.First, bcp2.Second, out minx, out maxx, out miny, out maxy);
             return;
         }
     }
 }
Beispiel #8
0
 /// <summary>
 /// ベジエ頂点の分割位置と角度を得る
 /// </summary>
 /// <param name="bcp1">ベジエ頂点1</param>
 /// <param name="bcp2">ベジエ頂点2</param>
 /// <param name="length">欲しい長さ</param>
 /// <param name="pos">位置</param>
 /// <param name="direction">向き</param>
 public static void GetBezeirSplitPoint(BezierControlPoint bcp1, BezierControlPoint bcp2, float length, out PointF pos, out PointF direction)
 {
     if (bcp1.ValidThird)
     {
         if (!bcp2.ValidFirst)
         {
             //second bezier
             GetBezeirSplitPoint(bcp1.Second, bcp1.Third, bcp2.Second, bcp2.Second, length, out pos, out direction);
             return;
         }
         else
         {
             //third bezier
             GetBezeirSplitPoint(bcp1.Second, bcp1.Third, bcp2.First, bcp2.Second, length, out pos, out direction);
             return;
         }
     }
     else
     {
         if (!bcp2.ValidFirst)
         {
             //first bezier
             var nv  = GetNormalizePoint(new PointF(bcp2.Second.X - bcp1.Second.X, bcp2.Second.Y - bcp1.Second.Y));
             var vec = new PointF(nv.X * length, nv.Y * length);
             pos       = new PointF(bcp1.Second.X + vec.X, bcp1.Second.Y + vec.Y);
             direction = nv;
             return;
         }
         else
         {
             //second bezier
             GetBezeirSplitPoint(bcp1.Second, bcp1.Second, bcp2.First, bcp2.Second, length, out pos, out direction);
             return;
         }
     }
 }
Beispiel #9
0
        /// <summary>
        /// デシリアライズメソッド
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static BezierControlPoint Deserialize(string str)
        {
            var ret = new BezierControlPoint();
            var fd  = new PointF(1, 0);
            var sec = new PointF(0, 0);
            var td  = new PointF(1, 0);

            foreach (string st in str.Split(' '))
            {
                var content = st.Split('=');
                if (content.Length != 2)
                {
                    throw new ArgumentException("Incorrect Format:" + st);
                }
                switch (content[0])
                {
                case "VF":
                    ret.ValidFirst = content[1] == "1";
                    break;

                case "VS":
                    ret.ValidSecond = content[1] == "1";
                    break;

                case "VT":
                    ret.ValidThird = content[1] == "1";
                    break;

                case "FDX":
                    fd.X = float.Parse(content[1], CultureInfo.InvariantCulture);
                    break;

                case "FDY":
                    fd.Y = float.Parse(content[1], CultureInfo.InvariantCulture);
                    break;

                case "SX":
                    sec.X = float.Parse(content[1], CultureInfo.InvariantCulture);
                    break;

                case "SY":
                    sec.Y = float.Parse(content[1], CultureInfo.InvariantCulture);
                    break;

                case "TDX":
                    td.X = float.Parse(content[1], CultureInfo.InvariantCulture);
                    break;

                case "TDY":
                    td.Y = float.Parse(content[1], CultureInfo.InvariantCulture);
                    break;

                case "FL":
                    ret.FirstLength = float.Parse(content[1], CultureInfo.InvariantCulture);
                    break;

                case "TL":
                    ret.ThirdLength = float.Parse(content[1], CultureInfo.InvariantCulture);
                    break;

                default:
                    throw new ArgumentException("Incorrect Argument:" + content[0]);
                }
            }
            ret.FirstDirection = fd;
            ret.Second         = sec;
            ret.ThirdDirection = td;
            return(ret);
        }