// This function returns a single closest point. There may be more than one point on the path at the same distance. // Use ComputeApproxParamPerUnitLength to determine a good paramThreshold. eg. Say you want a 15cm threshold, // use: paramThreshold = ComputeApproxParamPerUnitLength() * 0.15f. public float ComputeClosestParam(Vector3 pos, float paramThreshold) { float minDistSq = float.MaxValue; float closestParam = 0.0f; for (int startIndex = 0; startIndex < controlVerts.Length - 1; startIndex += 3) { Vector3[] curveCVs = new Vector3[4]; for (int i = 0; i < 4; i++) { curveCVs[i] = controlVerts[startIndex + i]; } CubicBezierCurve curve = new CubicBezierCurve(curveCVs); float curveClosestParam = curve.GetClosestParam(pos, paramThreshold); Vector3 curvePos = curve.GetPoint(curveClosestParam); float distSq = (curvePos - pos).sqrMagnitude; if (distSq < minDistSq) { minDistSq = distSq; float startParam = ((float)startIndex) / 3.0f; closestParam = startParam + curveClosestParam; } } return(closestParam); }
// This function returns a single closest point. There may be more than one point on the path at the same distance. // Use ComputeApproxParamPerUnitLength to determine a good paramThreshold. eg. Say you want a 15cm threshold, // use: paramThreshold = ComputeApproxParamPerUnitLength() * 0.15f. public float ComputeClosestParam(Vector3 pos, float paramThreshold) { var minDistSq = float.MaxValue; var closestParam = 0.0f; for (var startIndex = 0; startIndex < controlVerts.Length - 1; startIndex += 3) { var curve = new CubicBezierCurve(controlVerts[startIndex + 0], controlVerts[startIndex + 1], controlVerts[startIndex + 2], controlVerts[startIndex + 3]); var curveClosestParam = curve.GetClosestParam(pos, paramThreshold); var curvePos = curve.GetPoint(curveClosestParam); var distSq = (curvePos - pos).sqrMagnitude; if (distSq < minDistSq) { minDistSq = distSq; var startParam = ((float)startIndex) / 3.0f; closestParam = startParam + curveClosestParam; } } return(closestParam); }