/// <summary> /// Get the velocity of the curve for the t value /// </summary> /// <param name="t">value</param> /// <returns></returns> public Vector3 GetVelocity(float t) { return(transform.TransformPoint(Bezier.GetFirstDerivative(points[0], points[1], points[2], points[3], t)) - transform.position); }
/// <summary> /// Get the point in the curve corresponding to the t value. /// </summary> /// <param name="t">value</param> /// <returns></returns> public Vector3 GetPoint(float t) { return(transform.TransformPoint(Bezier.GetPoint(points[0], points[1], points[2], points[3], t))); }
public List <Vector3> CalculateEvenlySpacedPoints(float spacing, float resolution = 1, int startCurve = 0, int endCurve = -1) { if (endCurve == -1) { endCurve = CurveCount; } if (endCurve < startCurve) { throw new Exception("endCurve value can't be smaller than startCurve"); } if (startCurve > CurveCount) { throw new Exception("startCurve is bigger than curvecount"); } int numControlPoints = (endCurve - startCurve) * 3 + 1; if (controlPoints.Capacity < numControlPoints) { controlPoints = new List <Vector3>(numControlPoints); } for (int i = 0; i < numControlPoints; ++i) { controlPoints.Add(GetControlPoint(i + startCurve * 3)); } float estimatedSplineLength = 0; int numCurves = endCurve - startCurve; if (curveLengths.Capacity < numCurves) { curveLengths = new List <float>(numCurves); } // Calculate estimatedSplinelength for (int i = 0; i < controlPoints.Count - 1; i += 3) { Vector3 p0 = controlPoints[i], p1 = controlPoints[i + 1], p2 = controlPoints[i + 2], p3 = controlPoints[i + 3]; float chord = Vector3.Distance(p0, p3); float controlNetLength = Vector3.Distance(p0, p1) + Vector3.Distance(p1, p2) + Vector3.Distance(p2, p3); float estimatedCurveLength = (chord + controlNetLength) / 2f; curveLengths.Add(estimatedCurveLength); estimatedSplineLength += estimatedCurveLength; } #region EvenlySpacedPoints declaration if (EvenlySpacedPoints == null || EvenlySpacedPoints.Capacity < Mathf.RoundToInt(estimatedSplineLength / spacing)) { EvenlySpacedPoints = new List <Vector3>(Mathf.RoundToInt(estimatedSplineLength / spacing)); } EvenlySpacedPoints.Clear(); EvenlySpacedPoints.Add(points[startCurve * 3]); Vector3 previousPoint = points[startCurve * 3]; #endregion float distanceSinceLastEvenPoint = 0; for (int i = 0; i < curveLengths.Count; ++i) { int j = i * 3; int divisions = Mathf.CeilToInt(curveLengths[i] * resolution * 10); float t = 0; while (t <= 1) { t += 1f / divisions; Vector3 pointOnCurve = Bezier.GetPoint(controlPoints[j], controlPoints[j + 1], controlPoints[j + 2], controlPoints[j + 3], t); distanceSinceLastEvenPoint += Vector3.Distance(previousPoint, pointOnCurve); Vector3 normalizedDir = (previousPoint - pointOnCurve).normalized; while (distanceSinceLastEvenPoint >= spacing) { float overshootDistance = distanceSinceLastEvenPoint - spacing; Vector3 newEvenlySpacedPoint = pointOnCurve + normalizedDir * overshootDistance; EvenlySpacedPoints.Add(newEvenlySpacedPoint); distanceSinceLastEvenPoint = overshootDistance; previousPoint = newEvenlySpacedPoint; } previousPoint = pointOnCurve; } } curveLengths.Clear(); controlPoints.Clear(); return(EvenlySpacedPoints); }
public void setPoints( Vector3[] pts_, Quaternion[] rots ) { if(pts_.Length<4) Debug.LogError( "LeanTween - When passing values for a vector path, you must pass four or more values!" ); if(pts_.Length%4!=0) Debug.LogError( "LeanTween - When passing values for a vector path, they must be in sets of four: controlPoint1, controlPoint2, endPoint2, controlPoint2, controlPoint2..." ); pts = pts_; int k = 0; beziers = new Bezier[ pts.Length / 4 ]; lengthRatio = new float[ beziers.Length ]; int i; length = 0; for(i = 0; i < pts.Length; i+=4){ beziers[k] = new Bezier(pts[i+0],pts[i+2],pts[i+1],pts[i+3],0.05f, rots[i/4], rots[i/4+1]); length += beziers[k].length; k++; } // Debug.Log("beziers.Length:"+beziers.Length + " beziers:"+beziers); for(i = 0; i < beziers.Length; i++){ lengthRatio[i] = beziers[i].length / length; } }
/// <summary> /// 绘制画布事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void pictureBox1_Paint(object sender, PaintEventArgs e) { ///鼠标位置输出 label1.Text = "( " + poiCursor.X + ", " + poiCursor.Y + ") pixel"; ///鼠标位置被引力场捕获,绘制引力场 if (isGravitationCaptured != -1) { Graphics g = e.Graphics; if (isGravitationCaptured == madeBezierList.Count()) { ///当前是被 inputList 吸引 ///显示该点的引力场 g.DrawEllipse(new Pen(Color.Yellow), poiGravitation.X - myStatic.poi2poiDistMin, poiGravitation.Y - myStatic.poi2poiDistMin, myStatic.poi2poiDistMin * 2, myStatic.poi2poiDistMin * 2); g.FillRectangle(new SolidBrush(Color.Yellow), inputPoiList[CatchID].X - 2, inputPoiList[CatchID].Y - 2, 4, 4); } else { ///被 madeBezierList[isGravitationCaptured] 吸引 ///可能是被点或边捕获 if (CatchID < madeBezierList[isGravitationCaptured].P.poiList.Count()) { ///被点捕获,显示点的引力场 g.DrawEllipse(new Pen(Color.Yellow), poiGravitation.X - myStatic.poi2poiDistMin, poiGravitation.Y - myStatic.poi2poiDistMin, myStatic.poi2poiDistMin * 2, myStatic.poi2poiDistMin * 2); } else { ///被边捕获,显示边的引力场,画一个矩形+俩圆 int cou = CatchID - madeBezierList[isGravitationCaptured].P.poiList.Count(); Edge edge = new Edge(madeBezierList[isGravitationCaptured].P.poiList[cou], madeBezierList[isGravitationCaptured].P.poiList[cou + 1]); ///竖直的线段 if (edge.poi1.X == edge.poi2.X) { if (edge.poi1.Y > edge.poi2.Y) { g.DrawLine(new Pen(Color.Yellow), edge.poi1.X - myStatic.poi2edgeDistMin, edge.poi1.Y + myStatic.poi2edgeDistMin, edge.poi1.X + myStatic.poi2edgeDistMin, edge.poi1.Y + myStatic.poi2edgeDistMin); g.DrawLine(new Pen(Color.Yellow), edge.poi1.X + myStatic.poi2edgeDistMin, edge.poi1.Y + myStatic.poi2edgeDistMin, edge.poi2.X + myStatic.poi2edgeDistMin, edge.poi2.Y - myStatic.poi2edgeDistMin); g.DrawLine(new Pen(Color.Yellow), edge.poi2.X + myStatic.poi2edgeDistMin, edge.poi2.Y - myStatic.poi2edgeDistMin, edge.poi2.X - myStatic.poi2edgeDistMin, edge.poi2.Y - myStatic.poi2edgeDistMin); g.DrawLine(new Pen(Color.Yellow), edge.poi2.X - myStatic.poi2edgeDistMin, edge.poi2.Y - myStatic.poi2edgeDistMin, edge.poi1.X - myStatic.poi2edgeDistMin, edge.poi1.Y + myStatic.poi2edgeDistMin); } else { g.DrawLine(new Pen(Color.Yellow), edge.poi1.X - myStatic.poi2edgeDistMin, edge.poi1.Y - myStatic.poi2edgeDistMin, edge.poi1.X + myStatic.poi2edgeDistMin, edge.poi1.Y - myStatic.poi2edgeDistMin); g.DrawLine(new Pen(Color.Yellow), edge.poi1.X + myStatic.poi2edgeDistMin, edge.poi1.Y - myStatic.poi2edgeDistMin, edge.poi2.X + myStatic.poi2edgeDistMin, edge.poi2.Y + myStatic.poi2edgeDistMin); g.DrawLine(new Pen(Color.Yellow), edge.poi2.X + myStatic.poi2edgeDistMin, edge.poi2.Y + myStatic.poi2edgeDistMin, edge.poi2.X - myStatic.poi2edgeDistMin, edge.poi2.Y + myStatic.poi2edgeDistMin); g.DrawLine(new Pen(Color.Yellow), edge.poi2.X - myStatic.poi2edgeDistMin, edge.poi2.Y + myStatic.poi2edgeDistMin, edge.poi1.X - myStatic.poi2edgeDistMin, edge.poi1.Y - myStatic.poi2edgeDistMin); } } //水平的线段 else if (edge.poi1.Y == edge.poi2.Y) { if (edge.poi1.X > edge.poi2.X) { g.DrawLine(new Pen(Color.Yellow), edge.poi1.X + myStatic.poi2edgeDistMin, edge.poi1.Y + myStatic.poi2edgeDistMin, edge.poi1.X + myStatic.poi2edgeDistMin, edge.poi1.Y - myStatic.poi2edgeDistMin); g.DrawLine(new Pen(Color.Yellow), edge.poi1.X + myStatic.poi2edgeDistMin, edge.poi1.Y - myStatic.poi2edgeDistMin, edge.poi2.X - myStatic.poi2edgeDistMin, edge.poi2.Y - myStatic.poi2edgeDistMin); g.DrawLine(new Pen(Color.Yellow), edge.poi2.X - myStatic.poi2edgeDistMin, edge.poi2.Y - myStatic.poi2edgeDistMin, edge.poi2.X - myStatic.poi2edgeDistMin, edge.poi2.Y + myStatic.poi2edgeDistMin); g.DrawLine(new Pen(Color.Yellow), edge.poi2.X - myStatic.poi2edgeDistMin, edge.poi2.Y + myStatic.poi2edgeDistMin, edge.poi1.X + myStatic.poi2edgeDistMin, edge.poi1.Y + myStatic.poi2edgeDistMin); } else { g.DrawLine(new Pen(Color.Yellow), edge.poi1.X - myStatic.poi2edgeDistMin, edge.poi1.Y + myStatic.poi2edgeDistMin, edge.poi1.X - myStatic.poi2edgeDistMin, edge.poi1.Y - myStatic.poi2edgeDistMin); g.DrawLine(new Pen(Color.Yellow), edge.poi1.X - myStatic.poi2edgeDistMin, edge.poi1.Y - myStatic.poi2edgeDistMin, edge.poi2.X + myStatic.poi2edgeDistMin, edge.poi2.Y - myStatic.poi2edgeDistMin); g.DrawLine(new Pen(Color.Yellow), edge.poi2.X + myStatic.poi2edgeDistMin, edge.poi2.Y - myStatic.poi2edgeDistMin, edge.poi2.X + myStatic.poi2edgeDistMin, edge.poi2.Y + myStatic.poi2edgeDistMin); g.DrawLine(new Pen(Color.Yellow), edge.poi2.X + myStatic.poi2edgeDistMin, edge.poi2.Y + myStatic.poi2edgeDistMin, edge.poi1.X - myStatic.poi2edgeDistMin, edge.poi1.Y + myStatic.poi2edgeDistMin); } } ///倾斜的线段 else { ///边的缓冲区边界 g.DrawLine(new Pen(Color.Yellow, myStatic.poi2edgeDistMin * 2), edge.poi1, edge.poi2); g.DrawLine(new Pen(Color.White, (myStatic.poi2edgeDistMin - 1) * 2), edge.poi1, edge.poi2); ///端点的缓冲区边界 ///端点的缓冲区用的是边的引力大小 g.DrawEllipse(new Pen(Color.Yellow), edge.poi1.X - myStatic.poi2edgeDistMin, edge.poi1.Y - myStatic.poi2edgeDistMin, myStatic.poi2edgeDistMin * 2, myStatic.poi2edgeDistMin * 2); g.DrawEllipse(new Pen(Color.Yellow), edge.poi2.X - myStatic.poi2edgeDistMin, edge.poi2.Y - myStatic.poi2edgeDistMin, myStatic.poi2edgeDistMin * 2, myStatic.poi2edgeDistMin * 2); } } } } ///绘制已完成贝塞尔曲线对象 if (madeBezierList.Count() != 0) { foreach (Bezier bezier in madeBezierList) { if (isBorderVisible) { bezier.P.drawMyself(e, Color.Black); } bezier.drawMyself(e, Color.Blue); } } ///绘制当前绘制中的图形 if (!isDrawFinished) { Bezier bezierTemp = new Bezier(new Polyline(inputPoiList)); if (isBorderVisible) { bezierTemp.P.drawMyself(e, poiCursor); } bezierTemp.drawMyself(e, Color.Blue); } ///若有选中正在拖动,叠加显示 if (isCheck) { Graphics g = e.Graphics; ///选中的是点 ///绘制一个巨大的圆形,大小是点的引力场大小 if (CatchID < madeBezierList[isGravitationCaptured].P.poiList.Count()) { g.FillEllipse(new SolidBrush(Color.LightGreen), madeBezierList[isGravitationCaptured].P.poiList[CatchID].X - myStatic.poi2poiDistMin, madeBezierList[isGravitationCaptured].P.poiList[CatchID].Y - myStatic.poi2poiDistMin, myStatic.poi2poiDistMin * 2, myStatic.poi2poiDistMin * 2); } ///选中边 ///被选中的贝塞尔曲线的控制多边形变色 else { madeBezierList[isGravitationCaptured].P.drawMyself(e, Color.LightGreen); } } }