/// <summary> /// 単調増加ベジエの場合にのみ使用可。X座標からY座標を得る /// </summary> /// <param name="X"></param> /// <returns></returns> public float GetYFromX(float X) { float ret = 0; PointF p1 = BCPS[0].Second, p2 = BCPS[0].Second, p3 = BCPS[1].Second, p4 = BCPS[1].Second; if (BCPS[0].ValidThird) { p2 = BCPS[0].Third; } if (BCPS[1].ValidFirst) { p3 = BCPS[1].First; } float s = 0, e = 1; for (int i = 0; i < 20; i++) { float m = (s + e) / 2; var bp = BezierCaliculate.GetBezeirPoint(ref p1, ref p2, ref p3, ref p4, ref m); if (bp.X < X) { e = m; } else { s = m; } ret = bp.Y; } return(ret); }
/// <summary> /// ベジエ曲線状に乗っているか調べる /// </summary> /// <param name="p1">頂点1</param> /// <param name="p2">頂点2</param> /// <param name="p3">頂点3</param> /// <param name="p4">頂点4</param> /// <param name="target">調べる対象</param> /// <param name="outt">乗っていた時の割合(0~1)</param> /// <returns></returns> public static bool OnBezeier(PointF p1, PointF p2, PointF p3, PointF p4, PointF target, out float outt) { PointF lastbezierpoint, bezierpoint; lastbezierpoint = p1; outt = -1; float best = float.MaxValue; var count = BezierCaliculate.AboutBezeirCount(ref p1, ref p2, ref p3, ref p4); for (int i = count; i >= 0; i--) { float t = (float)i / count; bezierpoint = BezierCaliculate.GetBezeirPoint(ref p1, ref p2, ref p3, ref p4, ref t); var temp = GetLength(new PointF(bezierpoint.X - target.X, bezierpoint.Y - target.Y)); if (temp < best) { best = temp; outt = t; } lastbezierpoint = bezierpoint; } if (best <= 2) { return(true); } return(false); }
/// <summary> /// 4頂点からベジエ曲線上の位置を得る /// </summary> /// <param name="p1">頂点1</param> /// <param name="p2">頂点2</param> /// <param name="p3">頂点3</param> /// <param name="p4">頂点4</param> /// <returns></returns> public static IEnumerable <PointF> GetPoints(PointF p1, PointF p2, PointF p3, PointF p4) { var count = BezierCaliculate.AboutBezeirCount(ref p1, ref p2, ref p3, ref p4); for (int i = count; i >= 0; i--) { float t = (float)i / count; yield return(BezierCaliculate.GetBezeirPoint(ref p1, ref p2, ref p3, ref p4, ref t)); } }
private static float GetBezeierLength(PointF p1, PointF p2, PointF p3, PointF p4) { PointF lastbezierpoint, bezierpoint; lastbezierpoint = p1; float sum = 0; var count = BezierCaliculate.AboutBezeirCount(ref p1, ref p2, ref p3, ref p4); if (count == 0) { return(0); } for (int i = count; i >= 0; i--) { float t = (float)i / count; bezierpoint = BezierCaliculate.GetBezeirPoint(ref p1, ref p2, ref p3, ref p4, ref t); sum += GetLength(new PointF(bezierpoint.X - lastbezierpoint.X, bezierpoint.Y - lastbezierpoint.Y)); lastbezierpoint = bezierpoint; } return(sum); }
private static void GetBezeirSplitPoint(PointF p1, PointF p2, PointF p3, PointF p4, float length, out PointF pos, out PointF direction) { PointF lastbezierpoint, bezierpoint; lastbezierpoint = p1; pos = p1; direction = new PointF(1, 0); float sum = 0; var count = BezierCaliculate.AboutBezeirCount(ref p1, ref p2, ref p3, ref p4); for (int i = count; i >= 0; i--) { float t = (float)i / count; bezierpoint = BezierCaliculate.GetBezeirPoint(ref p1, ref p2, ref p3, ref p4, ref t); sum += GetLength(new PointF(bezierpoint.X - lastbezierpoint.X, bezierpoint.Y - lastbezierpoint.Y)); if (sum >= length) { pos = bezierpoint; direction = GetNormalizePoint(new PointF(bezierpoint.X - lastbezierpoint.X, bezierpoint.Y - lastbezierpoint.Y)); if (direction.X == 0 && direction.Y == 0) { t = (float)(i - 1) / count; lastbezierpoint = bezierpoint; bezierpoint = BezierCaliculate.GetBezeirPoint(ref p1, ref p2, ref p3, ref p4, ref t); direction = GetNormalizePoint(new PointF(bezierpoint.X - lastbezierpoint.X, bezierpoint.Y - lastbezierpoint.Y)); } return; } lastbezierpoint = bezierpoint; } pos = p4; direction = GetNormalizePoint(new PointF(p4.X - lastbezierpoint.X, p4.Y - lastbezierpoint.Y)); if (direction.X == 0 && direction.Y == 0) { float t = (float)1 / count; bezierpoint = BezierCaliculate.GetBezeirPoint(ref p1, ref p2, ref p3, ref p4, ref t); direction = GetNormalizePoint(new PointF(lastbezierpoint.X - bezierpoint.X, lastbezierpoint.Y - bezierpoint.Y)); } }