private Length ( System.Windows.Vector v ) : System.Double | ||
v | System.Windows.Vector | |
return | System.Double |
/// <summary> /// Gets the tangent for the the end of the curve. /// </summary> protected VECTOR GetRightTangent(int first) { List <VECTOR> pts = _pts; List <FLOAT> arclen = _arclen; FLOAT totalLen = arclen[arclen.Count - 1]; VECTOR p3 = pts[pts.Count - 1]; VECTOR tanR = VectorHelper.Normalize(pts[pts.Count - 2] - p3); VECTOR total = tanR; FLOAT weightTotal = 1; first = Math.Max(pts.Count - (END_TANGENT_N_PTS + 1), first + 1); for (int i = pts.Count - 3; i >= first; i--) { FLOAT t = arclen[i] / totalLen; FLOAT weight = t * t * t; VECTOR v = VectorHelper.Normalize(pts[i] - p3); total += v * weight; weightTotal += weight; } if (VectorHelper.Length(total) > EPSILON) { tanR = VectorHelper.Normalize(total / weightTotal); } return(tanR); }
/// <summary> /// Gets the tangent for the start of the cure. /// </summary> protected VECTOR GetLeftTangent(int last) { List <VECTOR> pts = _pts; List <FLOAT> arclen = _arclen; FLOAT totalLen = arclen[arclen.Count - 1]; VECTOR p0 = pts[0]; VECTOR tanL = VectorHelper.Normalize(pts[1] - p0); VECTOR total = tanL; FLOAT weightTotal = 1; last = Math.Min(END_TANGENT_N_PTS, last - 1); for (int i = 2; i <= last; i++) { FLOAT ti = 1 - (arclen[i] / totalLen); FLOAT weight = ti * ti * ti; VECTOR v = VectorHelper.Normalize(pts[i] - p0); total += v * weight; weightTotal += weight; } // if the vectors add up to zero (ie going opposite directions), there's no way to normalize them if (VectorHelper.Length(total) > EPSILON) { tanL = VectorHelper.Normalize(total / weightTotal); } return(tanL); }
/// <summary> /// Gets the tangent for the the end of the curve. /// </summary> protected Vector3 GetRightTangent(int first) { List <Vector3> pts = _pts; List <float> arclen = _arclen; float totalLen = arclen[arclen.Count - 1]; Vector3 p3 = pts[pts.Count - 1]; Vector3 tanR = VectorHelper.Normalize(pts[pts.Count - 2] - p3); Vector3 total = tanR; float weightTotal = 1; first = Math.Max(pts.Count - (END_TANGENT_N_PTS + 1), first + 1); for (int i = pts.Count - 3; i >= first; i--) { float t = arclen[i] / totalLen; float weight = t * t * t; Vector3 v = VectorHelper.Normalize(pts[i] - p3); total += v * weight; weightTotal += weight; } if (VectorHelper.Length(total) > EPSILON) { tanR = VectorHelper.Normalize(total / weightTotal); } return(tanR); }
public VECTOR Normal(FLOAT t) { try { var T1 = Derivative(t - 1e-4f); var T2 = Derivative(t + 1e-4f); var c = VectorHelper.Cross(T1 / VectorHelper.Length(T1), T2 / VectorHelper.Length(T2)); var N = VectorHelper.Cross(c, T1 / VectorHelper.Length(T1)); return(N / VectorHelper.Length(N)); } catch (DivideByZeroException e) { UnityEngine.Debug.Log(e.Message); return(UnityEngine.Vector3.right); } }
/// <summary> /// Gets the tangent at a given point in the curve. /// </summary> protected VECTOR GetCenterTangent(int first, int last, int split) { List <VECTOR> pts = _pts; List <FLOAT> arclen = _arclen; // because we want to maintain C1 continuity on the spline, the tangents on either side must be inverses of one another Debug.Assert(first < split && split < last); FLOAT splitLen = arclen[split]; VECTOR pSplit = pts[split]; // left side FLOAT firstLen = arclen[first]; FLOAT partLen = splitLen - firstLen; VECTOR total = default(VECTOR); FLOAT weightTotal = 0; for (int i = Math.Max(first, split - MID_TANGENT_N_PTS); i < split; i++) { FLOAT t = (arclen[i] - firstLen) / partLen; FLOAT weight = t * t * t; VECTOR v = VectorHelper.Normalize(pts[i] - pSplit); total += v * weight; weightTotal += weight; } VECTOR tanL = VectorHelper.Length(total) > EPSILON && weightTotal > EPSILON? VectorHelper.Normalize(total / weightTotal) : VectorHelper.Normalize(pts[split - 1] - pSplit); // right side partLen = arclen[last] - splitLen; int rMax = Math.Min(last, split + MID_TANGENT_N_PTS); total = default(VECTOR); weightTotal = 0; for (int i = split + 1; i <= rMax; i++) { FLOAT ti = 1 - ((arclen[i] - splitLen) / partLen); FLOAT weight = ti * ti * ti; VECTOR v = VectorHelper.Normalize(pSplit - pts[i]); total += v * weight; weightTotal += weight; } VECTOR tanR = VectorHelper.Length(total) > EPSILON && weightTotal > EPSILON? VectorHelper.Normalize(total / weightTotal) : VectorHelper.Normalize(pSplit - pts[split + 1]); // The reason we separate this into two halves is because we want the right and left tangents to be weighted // equally no matter the weights of the individual parts of them, so that one of the curves doesn't get screwed // for the pleasure of the other half total = tanL + tanR; // Since the points are never coincident, the vector between any two of them will be normalizable, however this can happen in some really // odd cases when the points are going directly opposite directions (therefore the tangent is undefined) if (VectorHelper.LengthSquared(total) < EPSILON) { // try one last time using only the three points at the center, otherwise just use one of the sides tanL = VectorHelper.Normalize(pts[split - 1] - pSplit); tanR = VectorHelper.Normalize(pSplit - pts[split + 1]); total = tanL + tanR; return(VectorHelper.LengthSquared(total) < EPSILON ? tanL : VectorHelper.Normalize(total / 2)); } else { return(VectorHelper.Normalize(total / 2)); } }