private float GetCurvePosition(float position) { CurveKey curveKey1 = this.keys[0]; for (int index = 1; index < this.keys.Count; ++index) { CurveKey curveKey2 = this.Keys[index]; if ((double)curveKey2.Position >= (double)position) { if (curveKey1.Continuity == CurveContinuity.Step) { if ((double)position >= 1.0) { return(curveKey2.Value); } else { return(curveKey1.Value); } } else { float num1 = (float)(((double)position - (double)curveKey1.Position) / ((double)curveKey2.Position - (double)curveKey1.Position)); float num2 = num1 * num1; float num3 = num2 * num1; return((float)((2.0 * (double)num3 - 3.0 * (double)num2 + 1.0) * (double)curveKey1.Value + ((double)num3 - 2.0 * (double)num2 + (double)num1) * (double)curveKey1.TangentOut + (3.0 * (double)num2 - 2.0 * (double)num3) * (double)curveKey2.Value + ((double)num3 - (double)num2) * (double)curveKey2.TangentIn)); } } else { curveKey1 = curveKey2; } } return(0.0f); }
private float GetCurvePosition(float position) { //only for position in curve CurveKey prev = this.keys[0]; CurveKey next; for (int i = 1; i < this.keys.Count; i++) { next = this.Keys[i]; if (next.Position >= position) { if (prev.Continuity == CurveContinuity.Step) { if (position >= 1f) { return(next.Value); } return(prev.Value); } float t = (position - prev.Position) / (next.Position - prev.Position);//to have t in [0,1] float ts = t * t; float tss = ts * t; //After a lot of search on internet I have found all about spline function // and bezier (phi'sss ancien) but finaly use hermite curve //http://en.wikipedia.org/wiki/Cubic_Hermite_spline //P(t) = (2*t^3 - 3t^2 + 1)*P0 + (t^3 - 2t^2 + t)m0 + (-2t^3 + 3t^2)P1 + (t^3-t^2)m1 //with P0.value = prev.value , m0 = prev.tangentOut, P1= next.value, m1 = next.TangentIn return((2 * tss - 3 * ts + 1f) * prev.Value + (tss - 2 * ts + t) * prev.TangentOut + (3 * ts - 2 * tss) * next.Value + (tss - ts) * next.TangentIn); } prev = next; } return(0f); }
public float Evaluate(float position) { CurveKey curveKey1 = this.keys[0]; CurveKey curveKey2 = this.keys[this.keys.Count - 1]; if ((double)position < (double)curveKey1.Position) { switch (this.PreLoop) { case CurveLoopType.Constant: return(curveKey1.Value); case CurveLoopType.Cycle: int numberOfCycle1 = this.GetNumberOfCycle(position); return(this.GetCurvePosition(position - (float)numberOfCycle1 * (curveKey2.Position - curveKey1.Position))); case CurveLoopType.CycleOffset: int numberOfCycle2 = this.GetNumberOfCycle(position); return(this.GetCurvePosition(position - (float)numberOfCycle2 * (curveKey2.Position - curveKey1.Position)) + (float)numberOfCycle2 * (curveKey2.Value - curveKey1.Value)); case CurveLoopType.Oscillate: int numberOfCycle3 = this.GetNumberOfCycle(position); return(this.GetCurvePosition(0.0 != (double)numberOfCycle3 % 2.0 ? (float)((double)curveKey2.Position - (double)position + (double)curveKey1.Position + (double)numberOfCycle3 * ((double)curveKey2.Position - (double)curveKey1.Position)) : position - (float)numberOfCycle3 * (curveKey2.Position - curveKey1.Position))); case CurveLoopType.Linear: return(curveKey1.Value - curveKey1.TangentIn * (curveKey1.Position - position)); } } else if ((double)position > (double)curveKey2.Position) { switch (this.PostLoop) { case CurveLoopType.Constant: return(curveKey2.Value); case CurveLoopType.Cycle: int numberOfCycle4 = this.GetNumberOfCycle(position); return(this.GetCurvePosition(position - (float)numberOfCycle4 * (curveKey2.Position - curveKey1.Position))); case CurveLoopType.CycleOffset: int numberOfCycle5 = this.GetNumberOfCycle(position); return(this.GetCurvePosition(position - (float)numberOfCycle5 * (curveKey2.Position - curveKey1.Position)) + (float)numberOfCycle5 * (curveKey2.Value - curveKey1.Value)); case CurveLoopType.Oscillate: int numberOfCycle6 = this.GetNumberOfCycle(position); float num = position - (float)numberOfCycle6 * (curveKey2.Position - curveKey1.Position); return(this.GetCurvePosition(0.0 != (double)numberOfCycle6 % 2.0 ? (float)((double)curveKey2.Position - (double)position + (double)curveKey1.Position + (double)numberOfCycle6 * ((double)curveKey2.Position - (double)curveKey1.Position)) : position - (float)numberOfCycle6 * (curveKey2.Position - curveKey1.Position))); case CurveLoopType.Linear: return(curveKey2.Value + curveKey1.TangentOut * (position - curveKey2.Position)); } } return(this.GetCurvePosition(position)); }
private float GetCurvePosition(float position) { // Only for position in curve. CurveKey prev = Keys[0]; CurveKey next; for (int i = 1; i < Keys.Count; i += 1) { next = Keys[i]; if (next.Position >= position) { if (prev.Continuity == CurveContinuity.Step) { if (position >= 1f) { return(next.Value); } return(prev.Value); } // To have t in [0,1] float t = ( (position - prev.Position) / (next.Position - prev.Position) ); float ts = t * t; float tss = ts * t; /* After a lot of search on internet I have found all about * spline function and bezier (phi'sss ancien) but finally * used hermite curve: * http://en.wikipedia.org/wiki/Cubic_Hermite_spline * P(t) = (2*t^3 - 3t^2 + 1)*P0 + (t^3 - 2t^2 + t)m0 + * (-2t^3 + 3t^2)P1 + (t^3-t^2)m1 * with P0.value = prev.value , m0 = prev.tangentOut, * P1= next.value, m1 = next.TangentIn. */ return( (2 * tss - 3 * ts + 1f) * prev.Value + (tss - 2 * ts + t) * prev.TangentOut + (3 * ts - 2 * tss) * next.Value + (tss - ts) * next.TangentIn ); } prev = next; } return(0f); }
private FP GetCurvePosition(FP position) { CurveKey curveKey = this.keys[0]; FP result; for (int i = 1; i < this.keys.Count; i++) { CurveKey curveKey2 = this.Keys[i]; bool flag = curveKey2.Position >= position; if (flag) { bool flag2 = curveKey.Continuity == CurveContinuity.Step; if (flag2) { bool flag3 = position >= 1f; if (flag3) { result = curveKey2.Value; } else { result = curveKey.Value; } } else { FP fP = (position - curveKey.Position) / (curveKey2.Position - curveKey.Position); FP fP2 = fP * fP; FP fP3 = fP2 * fP; result = (2 * fP3 - 3 * fP2 + 1f) * curveKey.Value + (fP3 - 2 * fP2 + fP) * curveKey.TangentOut + (3 * fP2 - 2 * fP3) * curveKey2.Value + (fP3 - fP2) * curveKey2.TangentIn; } return(result); } curveKey = curveKey2; } result = 0f; return(result); }
public float Evaluate(float position) { CurveKey first = keys[0]; CurveKey last = keys[keys.Count - 1]; if (position < first.Position) { switch (this.PreLoop) { case CurveLoopType.Constant: //constant return(first.Value); case CurveLoopType.Linear: // linear y = a*x +b with a tangeant of last point return(first.Value - first.TangentIn * (first.Position - position)); case CurveLoopType.Cycle: //start -> end / start -> end int cycle = GetNumberOfCycle(position); float virtualPos = position - (cycle * (last.Position - first.Position)); return(GetCurvePosition(virtualPos)); case CurveLoopType.CycleOffset: //make the curve continue (with no step) so must up the curve each cycle of delta(value) cycle = GetNumberOfCycle(position); virtualPos = position - (cycle * (last.Position - first.Position)); return(GetCurvePosition(virtualPos) + cycle * (last.Value - first.Value)); case CurveLoopType.Oscillate: //go back on curve from end and target start // start-> end / end -> start cycle = GetNumberOfCycle(position); if (0 == cycle % 2f) //if pair { virtualPos = position - (cycle * (last.Position - first.Position)); } else { virtualPos = last.Position - position + first.Position + (cycle * (last.Position - first.Position)); } return(GetCurvePosition(virtualPos)); } } else if (position > last.Position) { int cycle; switch (this.PostLoop) { case CurveLoopType.Constant: //constant return(last.Value); case CurveLoopType.Linear: // linear y = a*x +b with a tangeant of last point return(last.Value + first.TangentOut * (position - last.Position)); case CurveLoopType.Cycle: //start -> end / start -> end cycle = GetNumberOfCycle(position); float virtualPos = position - (cycle * (last.Position - first.Position)); return(GetCurvePosition(virtualPos)); case CurveLoopType.CycleOffset: //make the curve continue (with no step) so must up the curve each cycle of delta(value) cycle = GetNumberOfCycle(position); virtualPos = position - (cycle * (last.Position - first.Position)); return(GetCurvePosition(virtualPos) + cycle * (last.Value - first.Value)); case CurveLoopType.Oscillate: //go back on curve from end and target start // start-> end / end -> start cycle = GetNumberOfCycle(position); virtualPos = position - (cycle * (last.Position - first.Position)); if (0 == cycle % 2f) //if pair { virtualPos = position - (cycle * (last.Position - first.Position)); } else { virtualPos = last.Position - position + first.Position + (cycle * (last.Position - first.Position)); } return(GetCurvePosition(virtualPos)); } } //in curve return(GetCurvePosition(position)); }
/// <summary> /// Computes tangent for the specific key in the collection. /// </summary> /// <param name="keyIndex">The index of key in the collection.</param> /// <param name="tangentInType">The tangent in-type. <see cref="CurveKey.TangentIn"/> for more details.</param> /// <param name="tangentOutType">The tangent out-type. <see cref="CurveKey.TangentOut"/> for more details.</param> public void ComputeTangent( int keyIndex, CurveTangent tangentInType, CurveTangent tangentOutType ) { // See http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.curvetangent.aspx CurveKey key = Keys[keyIndex]; float p0, p, p1; p0 = p = p1 = key.Position; float v0, v, v1; v0 = v = v1 = key.Value; if (keyIndex > 0) { p0 = Keys[keyIndex - 1].Position; v0 = Keys[keyIndex - 1].Value; } if (keyIndex < Keys.Count - 1) { p1 = Keys[keyIndex + 1].Position; v1 = Keys[keyIndex + 1].Value; } switch (tangentInType) { case CurveTangent.Flat: key.TangentIn = 0; break; case CurveTangent.Linear: key.TangentIn = v - v0; break; case CurveTangent.Smooth: float pn = p1 - p0; if (MathHelper.WithinEpsilon(pn, 0.0f)) { key.TangentIn = 0; } else { key.TangentIn = (v1 - v0) * ((p - p0) / pn); } break; } switch (tangentOutType) { case CurveTangent.Flat: key.TangentOut = 0; break; case CurveTangent.Linear: key.TangentOut = v1 - v; break; case CurveTangent.Smooth: float pn = p1 - p0; if (Math.Abs(pn) < float.Epsilon) { key.TangentOut = 0; } else { key.TangentOut = (v1 - v0) * ((p1 - p) / pn); } break; } }
/// <summary> /// Evaluate the value at a position of this <see cref="Curve"/>. /// </summary> /// <param name="position">The position on this <see cref="Curve"/>.</param> /// <returns>Value at the position on this <see cref="Curve"/>.</returns> public float Evaluate(float position) { if (Keys.Count == 0) { return(0.0f); } if (Keys.Count == 1) { return(Keys[0].Value); } CurveKey first = Keys[0]; CurveKey last = Keys[Keys.Count - 1]; if (position < first.Position) { switch (this.PreLoop) { case CurveLoopType.Constant: return(first.Value); case CurveLoopType.Linear: // Linear y = a*x +b with a tangent of last point. return(first.Value - first.TangentIn * (first.Position - position)); case CurveLoopType.Cycle: // Start -> end / start -> end... int cycle = GetNumberOfCycle(position); float virtualPos = position - (cycle * (last.Position - first.Position)); return(GetCurvePosition(virtualPos)); case CurveLoopType.CycleOffset: /* Make the curve continue (with no step) so must up * the curve each cycle of delta(value). */ cycle = GetNumberOfCycle(position); virtualPos = position - (cycle * (last.Position - first.Position)); return(GetCurvePosition(virtualPos) + cycle * (last.Value - first.Value)); case CurveLoopType.Oscillate: /* Go back on curve from end and target start * Start-> end / end -> start... */ cycle = GetNumberOfCycle(position); if (0 == cycle % 2f) { virtualPos = position - (cycle * (last.Position - first.Position)); } else { virtualPos = last.Position - position + first.Position + (cycle * (last.Position - first.Position)); } return(GetCurvePosition(virtualPos)); } } else if (position > last.Position) { int cycle; switch (this.PostLoop) { case CurveLoopType.Constant: return(last.Value); case CurveLoopType.Linear: // Linear y = a*x +b with a tangent of last point. return(last.Value + first.TangentOut * (position - last.Position)); case CurveLoopType.Cycle: // Start -> end / start -> end... cycle = GetNumberOfCycle(position); float virtualPos = position - (cycle * (last.Position - first.Position)); return(GetCurvePosition(virtualPos)); case CurveLoopType.CycleOffset: /* Make the curve continue (with no step) so must up * the curve each cycle of delta(value). */ cycle = GetNumberOfCycle(position); virtualPos = position - (cycle * (last.Position - first.Position)); return(GetCurvePosition(virtualPos) + cycle * (last.Value - first.Value)); case CurveLoopType.Oscillate: /* Go back on curve from end and target start. * Start-> end / end -> start... */ cycle = GetNumberOfCycle(position); virtualPos = position - (cycle * (last.Position - first.Position)); if (0 == cycle % 2f) { virtualPos = position - (cycle * (last.Position - first.Position)); } else { virtualPos = last.Position - position + first.Position + (cycle * (last.Position - first.Position) ); } return(GetCurvePosition(virtualPos)); } } // In curve. return(GetCurvePosition(position)); }
public void ComputeTangent(int keyIndex, CurveTangent tangentInType, CurveTangent tangentOutType) { CurveKey curveKey = this.keys[keyIndex]; double num1; float num2 = (float)(num1 = (double)curveKey.Position); float num3 = (float)num1; float num4 = (float)num1; double num5; float num6 = (float)(num5 = (double)curveKey.Value); float num7 = (float)num5; float num8 = (float)num5; if (keyIndex > 0) { num4 = this.keys[keyIndex - 1].Position; num8 = this.keys[keyIndex - 1].Value; } if (keyIndex < this.keys.Count - 1) { num2 = this.keys[keyIndex + 1].Position; num6 = this.keys[keyIndex + 1].Value; } switch (tangentInType) { case CurveTangent.Flat: curveKey.TangentIn = 0.0f; break; case CurveTangent.Linear: curveKey.TangentIn = num7 - num8; break; case CurveTangent.Smooth: float num9 = num2 - num4; curveKey.TangentIn = (double)Math.Abs(num9) >= 1.40129846432482E-45 ? (float)(((double)num6 - (double)num8) * (((double)num3 - (double)num4) / (double)num9)) : 0.0f; break; } switch (tangentOutType) { case CurveTangent.Flat: curveKey.TangentOut = 0.0f; break; case CurveTangent.Linear: curveKey.TangentOut = num6 - num7; break; case CurveTangent.Smooth: float num10 = num2 - num4; if ((double)Math.Abs(num10) < 1.40129846432482E-45) { curveKey.TangentOut = 0.0f; break; } else { curveKey.TangentOut = (float)(((double)num6 - (double)num8) * (((double)num2 - (double)num3) / (double)num10)); break; } } }
public FP Evaluate(FP position) { CurveKey curveKey = this.keys[0]; CurveKey curveKey2 = this.keys[this.keys.Count - 1]; bool flag = position < curveKey.Position; FP result; if (flag) { switch (this.PreLoop) { case CurveLoopType.Constant: result = curveKey.Value; return(result); case CurveLoopType.Cycle: { int numberOfCycle = this.GetNumberOfCycle(position); FP position2 = position - numberOfCycle * (curveKey2.Position - curveKey.Position); result = this.GetCurvePosition(position2); return(result); } case CurveLoopType.CycleOffset: { int numberOfCycle = this.GetNumberOfCycle(position); FP position2 = position - numberOfCycle * (curveKey2.Position - curveKey.Position); result = this.GetCurvePosition(position2) + numberOfCycle * (curveKey2.Value - curveKey.Value); return(result); } case CurveLoopType.Oscillate: { int numberOfCycle = this.GetNumberOfCycle(position); bool flag2 = 0f == (float)numberOfCycle % 2f; FP position2; if (flag2) { position2 = position - numberOfCycle * (curveKey2.Position - curveKey.Position); } else { position2 = curveKey2.Position - position + curveKey.Position + numberOfCycle * (curveKey2.Position - curveKey.Position); } result = this.GetCurvePosition(position2); return(result); } case CurveLoopType.Linear: result = curveKey.Value - curveKey.TangentIn * (curveKey.Position - position); return(result); } } else { bool flag3 = position > curveKey2.Position; if (flag3) { switch (this.PostLoop) { case CurveLoopType.Constant: result = curveKey2.Value; return(result); case CurveLoopType.Cycle: { int numberOfCycle2 = this.GetNumberOfCycle(position); FP position3 = position - numberOfCycle2 * (curveKey2.Position - curveKey.Position); result = this.GetCurvePosition(position3); return(result); } case CurveLoopType.CycleOffset: { int numberOfCycle2 = this.GetNumberOfCycle(position); FP position3 = position - numberOfCycle2 * (curveKey2.Position - curveKey.Position); result = this.GetCurvePosition(position3) + numberOfCycle2 * (curveKey2.Value - curveKey.Value); return(result); } case CurveLoopType.Oscillate: { int numberOfCycle2 = this.GetNumberOfCycle(position); FP position3 = position - numberOfCycle2 * (curveKey2.Position - curveKey.Position); bool flag4 = 0f == (float)numberOfCycle2 % 2f; if (flag4) { position3 = position - numberOfCycle2 * (curveKey2.Position - curveKey.Position); } else { position3 = curveKey2.Position - position + curveKey.Position + numberOfCycle2 * (curveKey2.Position - curveKey.Position); } result = this.GetCurvePosition(position3); return(result); } case CurveLoopType.Linear: result = curveKey2.Value + curveKey.TangentOut * (position - curveKey2.Position); return(result); } } } result = this.GetCurvePosition(position); return(result); }