private GetY ( System.Windows.Vector v ) : System.Double | ||
v | System.Windows.Vector | |
return | System.Double |
/// <summary> /// Attempts to find a slightly better parameterization for u on the given curve. /// </summary> protected void Reparameterize(int first, int last, CubicBezier curve) { List <VECTOR> pts = _pts; List <FLOAT> u = _u; int nPts = last - first; for (int i = 1; i < nPts; i++) { VECTOR p = pts[first + i]; FLOAT t = u[i]; FLOAT ti = 1 - t; // Control vertices for Q' VECTOR qp0 = (curve.p1 - curve.p0) * 3; VECTOR qp1 = (curve.p2 - curve.p1) * 3; VECTOR qp2 = (curve.p3 - curve.p2) * 3; // Control vertices for Q'' VECTOR qpp0 = (qp1 - qp0) * 2; VECTOR qpp1 = (qp2 - qp1) * 2; // Evaluate Q(t), Q'(t), and Q''(t) VECTOR p0 = curve.Sample(t); VECTOR p1 = ((ti * ti) * qp0) + ((2 * ti * t) * qp1) + ((t * t) * qp2); VECTOR p2 = (ti * qpp0) + (t * qpp1); // these are the actual fitting calculations using http://en.wikipedia.org/wiki/Newton%27s_method // We can't just use .X and .Y because Unity uses lower-case "x" and "y". FLOAT num = ((VectorHelper.GetX(p0) - VectorHelper.GetX(p)) * VectorHelper.GetX(p1)) + ((VectorHelper.GetY(p0) - VectorHelper.GetY(p)) * VectorHelper.GetY(p1)); FLOAT den = (VectorHelper.GetX(p1) * VectorHelper.GetX(p1)) + (VectorHelper.GetY(p1) * VectorHelper.GetY(p1)) + ((VectorHelper.GetX(p0) - VectorHelper.GetX(p)) * VectorHelper.GetX(p2)) + ((VectorHelper.GetY(p0) - VectorHelper.GetY(p)) * VectorHelper.GetY(p2)); FLOAT newU = t - num / den; if (Math.Abs(den) > EPSILON && newU >= 0 && newU <= 1) { u[i] = newU; } } }
private static void RdpRecursive(List <VECTOR> pts, FLOAT error, int first, int last, List <int> keepIndex) { int nPts = last - first + 1; if (nPts < 3) { return; } VECTOR a = pts[first]; VECTOR b = pts[last]; FLOAT abDist = VectorHelper.Distance(a, b); FLOAT aCrossB = VectorHelper.GetX(a) * VectorHelper.GetY(b) - VectorHelper.GetX(b) * VectorHelper.GetY(a); FLOAT maxDist = error; int split = 0; for (int i = first + 1; i < last - 1; i++) { VECTOR p = pts[i]; FLOAT pDist = PerpendicularDistance(a, b, abDist, aCrossB, p); if (pDist > maxDist) { maxDist = pDist; split = i; } } if (split != 0) { keepIndex.Add(split); RdpRecursive(pts, error, first, split, keepIndex); RdpRecursive(pts, error, split, last, keepIndex); } }
public override int GetHashCode() { JenkinsHash hash = new JenkinsHash(); hash.Mixin(VectorHelper.GetX(p0).GetHashCode()); hash.Mixin(VectorHelper.GetY(p0).GetHashCode()); hash.Mixin(VectorHelper.GetX(p1).GetHashCode()); hash.Mixin(VectorHelper.GetY(p1).GetHashCode()); hash.Mixin(VectorHelper.GetX(p2).GetHashCode()); hash.Mixin(VectorHelper.GetY(p2).GetHashCode()); hash.Mixin(VectorHelper.GetX(p3).GetHashCode()); hash.Mixin(VectorHelper.GetY(p3).GetHashCode()); return(hash.GetValue()); }
[MethodImpl(MethodImplOptions.AggressiveInlining)] // originally this method wasn't be inlined #endif private static FLOAT PerpendicularDistance(VECTOR a, VECTOR b, FLOAT abDist, FLOAT aCrossB, VECTOR p) { // a profile with the test data showed that originally this was eating up ~44% of the runtime. So, this went through // several iterations of optimization and staring at the disassembly. I tried different methods of using cross // products, doing the computation with larger vector types, etc... this is the best I could do in ~45 minutes // running on 3 hours of sleep, which is all scalar math, but RyuJIT puts it into XMM registers and does // ADDSS/SUBSS/MULSS/DIVSS because that's what it likes to do whenever it sees a vector in a function. FLOAT area = Math.Abs(aCrossB + VectorHelper.GetX(b) * VectorHelper.GetY(p) + VectorHelper.GetX(p) * VectorHelper.GetY(a) - VectorHelper.GetX(p) * VectorHelper.GetY(b) - VectorHelper.GetX(a) * VectorHelper.GetY(p)); FLOAT height = area / abDist; return(height); }
public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append("CubicBezier: (<"); sb.Append(VectorHelper.GetX(p0).ToString("#.###", CultureInfo.InvariantCulture)); sb.Append(", "); sb.Append(VectorHelper.GetY(p0).ToString("#.###", CultureInfo.InvariantCulture)); sb.Append("> <"); sb.Append(VectorHelper.GetX(p1).ToString("#.###", CultureInfo.InvariantCulture)); sb.Append(", "); sb.Append(VectorHelper.GetY(p1).ToString("#.###", CultureInfo.InvariantCulture)); sb.Append("> <"); sb.Append(VectorHelper.GetX(p2).ToString("#.###", CultureInfo.InvariantCulture)); sb.Append(", "); sb.Append(VectorHelper.GetY(p2).ToString("#.###", CultureInfo.InvariantCulture)); sb.Append("> <"); sb.Append(VectorHelper.GetX(p3).ToString("#.###", CultureInfo.InvariantCulture)); sb.Append(", "); sb.Append(VectorHelper.GetY(p3).ToString("#.###", CultureInfo.InvariantCulture)); sb.Append(">)"); return(sb.ToString()); }