protected override void calculateBasisFunction(ICurveParam curveParam) { if (curveParam.getCurveType() == InterpolationCurveType.nurbsCurve) { NurbsCurveParam param = (NurbsCurveParam)curveParam; Dynamic2DArray<PiecewiseIntervalPolynomialCurveElement> basisFunctions = new Dynamic2DArray<PiecewiseIntervalPolynomialCurveElement>(); int total = param.Degree + param.PointList.Count; DoubleExtension denominator10, denominator20, numerator11, numerator10, numerator21, numerator20; PiecewiseIntervalPolynomialCurveElement curve1, curve2; numerator11 = new DoubleExtension(1); numerator21 = new DoubleExtension(-1); for (int i = 0; i < total; i++) { basisFunctions.SetArrayElement(0, i, new PiecewiseIntervalPolynomialCurveElement(i, param.Interval)); } for (int i = 1; i <= param.Degree; i++) { for (int j = 0; j < total - i; j++) { denominator10 = param.Interval.CutPoints[i + j] - param.Interval.CutPoints[j]; denominator20 = param.Interval.CutPoints[i + j + 1] - param.Interval.CutPoints[j + 1]; numerator10 = 0 - param.Interval.CutPoints[j]; numerator20 = param.Interval.CutPoints[i + j + 1]; curve1 = basisFunctions.GetArrayElement(i - 1, j).DivideByNumber(denominator10).MultiplyByLinear(numerator11, numerator10); curve2 = basisFunctions.GetArrayElement(i - 1, j + 1).DivideByNumber(denominator20).MultiplyByLinear(numerator21, numerator20); basisFunctions.SetArrayElement(i, j, curve1 + curve2); } } this.basisFunctions = basisFunctions[param.Degree]; } else { throw new UnmatchedCurveParamTypeException(InterpolationCurveType.nurbsCurve, curveParam.getCurveType()); } }
public void GraphPane_AxisChangeEvent(GraphPane pane) { if (sameStepForXY) { double realHeight = (zedGraphControl.GraphPane.YAxis.Scale.Max - zedGraphControl.GraphPane.YAxis.Scale.Min) * heightMultiplier; double realWidth = zedGraphControl.GraphPane.XAxis.Scale.Max - zedGraphControl.GraphPane.XAxis.Scale.Min; DoubleExtension multiplier, smallVal, bigVal; if (realHeight > realWidth) { multiplier = new DoubleExtension(realHeight / realWidth); MathExtension.MiddleBasedResize(new DoubleExtension(zedGraphControl.GraphPane.XAxis.Scale.Min), new DoubleExtension(zedGraphControl.GraphPane.XAxis.Scale.Max), multiplier, out smallVal, out bigVal); zedGraphControl.GraphPane.XAxis.Scale.Min = smallVal.AccurateValue; zedGraphControl.GraphPane.XAxis.Scale.Max = bigVal.AccurateValue; zedGraphControl.GraphPane.XAxis.Scale.MajorStep = MathExtension.DynamicRound((bigVal.AccurateValue - smallVal.AccurateValue) / 6); zedGraphControl.GraphPane.XAxis.Scale.MinorStep = MathExtension.DynamicRound((bigVal.AccurateValue - smallVal.AccurateValue) / 6) / 4; } else { multiplier = new DoubleExtension(realWidth / realHeight); MathExtension.MiddleBasedResize(new DoubleExtension(zedGraphControl.GraphPane.YAxis.Scale.Min), new DoubleExtension(zedGraphControl.GraphPane.YAxis.Scale.Max), multiplier, out smallVal, out bigVal); zedGraphControl.GraphPane.YAxis.Scale.Min = smallVal.AccurateValue; zedGraphControl.GraphPane.YAxis.Scale.Max = bigVal.AccurateValue; zedGraphControl.GraphPane.YAxis.Scale.MajorStep = MathExtension.DynamicRound((bigVal.AccurateValue - smallVal.AccurateValue) / 6); zedGraphControl.GraphPane.YAxis.Scale.MinorStep = MathExtension.DynamicRound((bigVal.AccurateValue - smallVal.AccurateValue) / 6) / 4; } } }
public CubicSplineInterpolationCurveParam(List<DataPoint> points, CSIBorderConditionType curveType, DoubleExtension val1, DoubleExtension val2) { pointList = new OrderedCurvePointList(points); csiConditionType = curveType; leftVal = val1; rightVal = val2; interval = new PiecewiseDataInterval(pointList); }
public DataVector(DoubleExtension val1, DoubleExtension val2) { xDiff = val1; yDiff = val2; if (xDiff != 0 || yDiff != 0) { isZero = false; } }
public DataVector(DataPoint pt1, DataPoint pt2) { xDiff = pt2.X - pt1.X; yDiff = pt2.Y - pt1.Y; if (xDiff != 0 || yDiff != 0) { isZero = false; } }
public NormalIntervalPolynomialCurveElement(DoubleExtension val, DataInterval interval) { this.degree = 1; this.coefficients = new List<DoubleExtension>(); this.coefficients.Add(val); this.interval = interval; if (val.EqualsToZero) this.equalsToZero = true; }
public override DoubleExtension calculate(DoubleExtension doubleExtension) { if (!interval.IsBetweenBordersCloseInterval(doubleExtension)) throw new ArgumentOutOfRangeException("doubleExtension", "The value given is out of borders of intervals. Value: " + doubleExtension.ApproximateString + ", Range: [" + interval.LeftBorder.ApproximateString + ", " + interval.RightBorder.ApproximateString + "]."); double result = 0; double poweredX = 1; for (int i = 0; i < degree; i++) { result += poweredX * fullCoefficents.GetArrayElement(i, 0).AccurateValue; poweredX *= doubleExtension.AccurateValue - list[i].X.AccurateValue; } return new DoubleExtension(result); }
public override DoubleExtension calculate(DoubleExtension doubleExtension) { int i = interval.IndexOfInterval(doubleExtension); if (i > -1) { Debug.Assert(interval[i].IsBetweenBordersCloseInterval(doubleExtension), "Can't find proper interval for given value."); return polynomialCurves[i].calculate(doubleExtension); } else { throw new ArgumentOutOfRangeException("doubleExtension", "This parameter is out of range."); } }
public override DataPoint calculatePoint(DoubleExtension doubleExtension) { Debug.Assert(doubleExtension <= interval.RightBorder && doubleExtension >= interval.LeftBorder, "The parameter is out of range for BezierCurve."); double xVal = 0; double yVal = 0; double basisFunction = 1; for (int i = 0; i < pointList.Count; i++) { basisFunction = calculateBasisFunction(doubleExtension, pointList.Count - 1, i).AccurateValue; xVal += basisFunction * pointList[i].X.AccurateValue; yVal += basisFunction * pointList[i].Y.AccurateValue; } return new DataPoint(xVal, yVal); }
public override DataPoint calculatePoint(DoubleExtension doubleExtension) { Debug.Assert(interval.IsBetweenBordersCloseInterval(doubleExtension), "Invalid argument for NurbsParametricCurveElement.calculatePoint()"); DoubleExtension xVal = new DoubleExtension(0); DoubleExtension yVal = new DoubleExtension(0); DoubleExtension basisFunction; DoubleExtension denominator = new DoubleExtension(0); for (int i = 0; i < pointList.Count; i++) { basisFunction = basisFunctions[i].calculate(doubleExtension) * weights[i]; xVal += basisFunction * pointList[i].X; yVal += basisFunction * pointList[i].Y; denominator += basisFunction.AccurateValue; } return new DataPoint(xVal / denominator, yVal / denominator); }
public DataVector(DoubleExtension arc, bool positive) { if (arc == Math.PI / 2.0) { xDiff = DoubleExtension.ZERO; yDiff = DoubleExtension.POSITIVE_ONE; } else if (arc == Math.PI / (-2.0)) { xDiff = DoubleExtension.ZERO; yDiff = DoubleExtension.NEGATIVE_ONE; } else if (positive) { xDiff = DoubleExtension.POSITIVE_ONE; yDiff = new DoubleExtension(Math.Tan(arc.AccurateValue)); } else { xDiff = DoubleExtension.NEGATIVE_ONE; yDiff = new DoubleExtension(0 - Math.Tan(arc.AccurateValue)); } isZero = false; }
public NormalIntervalPolynomialCurveElement DivideByNumber(DoubleExtension val) { if (EqualsToZero) { return new NormalIntervalPolynomialCurveElement(new DoubleExtension(0), Interval); } if (val.EqualsToZero) { throw new DivideByZeroException("The polynomial coefficients are divided by 0."); } List<DoubleExtension> newCoefficients = new List<DoubleExtension>(); for (int i = 0; i < coefficients.Count; i++) { newCoefficients.Add(coefficients[i] / val); } return new NormalIntervalPolynomialCurveElement(newCoefficients, newCoefficients.Count, Interval); }
/// <summary> /// /// </summary> /// <param name="points">型值点</param> /// <param name="curveType">边界条件类型</param> /// <param name="val1"></param> /// <param name="val2"></param> /// <param name="val3"></param> /// <param name="val4"></param> public ParametricCubicSplineInterpolationCurveParam(List<DataPoint> points, PCSIBorderConditionType curveType, DoubleExtension val1, DoubleExtension val2, DoubleExtension val3, DoubleExtension val4) { DoubleExtension subValLeftX = DoubleExtension.ZERO, subValRightX = DoubleExtension.ZERO, subValLeftY = DoubleExtension.ZERO, subValRightY = DoubleExtension.ZERO; CSIBorderConditionType subType = CSIBorderConditionType.First_Order_Derivative; List<DataPoint> xPointList = new List<DataPoint>(); List<DataPoint> yPointList = new List<DataPoint>(); if (points.Count < 2) throw new ArgumentException("At least two points are needed for PCSI Curve drawing."); pointList = new NormalCurvePointList(points); xPointList.Add(new DataPoint(DoubleExtension.ZERO, points[0].X)); yPointList.Add(new DataPoint(DoubleExtension.ZERO, points[0].Y)); DoubleExtension accumulatedChordLength = DoubleExtension.ZERO; List<DoubleExtension> cutPoints = new List<DoubleExtension>(); cutPoints.Add(accumulatedChordLength); for (int i = 1; i < points.Count; i++) { accumulatedChordLength += DataPoint.CalculateDistance(points[i - 1], points[i]); cutPoints.Add(accumulatedChordLength); xPointList.Add(new DataPoint(accumulatedChordLength, points[i].X)); yPointList.Add(new DataPoint(accumulatedChordLength, points[i].Y)); } this.interval = new PiecewiseDataInterval(cutPoints); switch (curveType) { case PCSIBorderConditionType.First_Order_Derivative: subType = CSIBorderConditionType.First_Order_Derivative; DoubleExtension arcLeft1 = new DoubleExtension(Math.Atan(val1.AccurateValue)); DoubleExtension arcRight1 = new DoubleExtension(Math.Atan(val2.AccurateValue)); subValLeftX = new DoubleExtension(Math.Cos(arcLeft1.AccurateValue)); subValLeftY = new DoubleExtension(Math.Sin(arcLeft1.AccurateValue)); subValRightX = new DoubleExtension(Math.Cos(arcRight1.AccurateValue)); subValRightY = new DoubleExtension(Math.Sin(arcRight1.AccurateValue)); //DataVector referenceArcLeft1 = new DataVector(points[0], points[1]); //DataVector referenceArcRight1 = new DataVector(points[points.Count - 2], points[points.Count - 1]); //bool flagLeft = referenceArcLeft.GetTheFlagForCloserArc(arcLeft); //bool flagRight = referenceArcRight.GetTheFlagForCloserArc(arcRight); //if (flagLeft) //{ // subValLeftX = new DoubleExtension(Math.Cos(arcLeft.AccurateValue)); // subValLeftY = new DoubleExtension(Math.Sin(arcLeft.AccurateValue)); //} //else //{ // subValLeftX = new DoubleExtension(0 - Math.Cos(arcLeft.AccurateValue));; // subValLeftY = new DoubleExtension(0 - Math.Sin(arcLeft.AccurateValue)); //} //if (flagRight) //{ // subValRightX = new DoubleExtension(Math.Cos(arcRight.AccurateValue)); // subValRightY = new DoubleExtension(Math.Sin(arcRight.AccurateValue)); //} //else //{ // subValRightX = new DoubleExtension(Math.Cos(0 - arcRight.AccurateValue)); // subValRightY = new DoubleExtension(Math.Sin(0 - arcRight.AccurateValue)); //} break; case PCSIBorderConditionType.Zero_Curvature: subType = CSIBorderConditionType.Second_Order_Derivative; break; case PCSIBorderConditionType.Centre_of_Curvature: if (val1 == points[0].X && val3 == points[0].Y) { throw new ArgumentException("The center of the left border's curvature is the same as the left border point."); } if (val2 == points[points.Count - 1].X && val4 == points[points.Count - 1].Y) { throw new ArgumentException("The center of the right border's curvature is the same as the right border point."); } // // Second_Order_Derivative // //subType = CSIBorderConditionType.Second_Order_Derivative; //DoubleExtension denominator1 = new DoubleExtension(Math.Pow(val1.AccurateValue - points[0].X.AccurateValue, 2) + Math.Pow(val3.AccurateValue - points[0].Y.AccurateValue, 2)); //DoubleExtension denominator2 = new DoubleExtension(Math.Pow(val2.AccurateValue - points[points.Count - 1].X.AccurateValue, 2) + Math.Pow(val4.AccurateValue - points[points.Count - 1].Y.AccurateValue, 2)); //subValLeftX = (val1 - points[0].X) / denominator1; //subValLeftY = (val3 - points[0].Y) / denominator1; //subValRightX = (val2 - points[points.Count - 1].X) / denominator2; //subValRightY = (val4 - points[points.Count - 1].Y) / denominator2; // // First_Order_Derivative // subType = CSIBorderConditionType.First_Order_Derivative; DoubleExtension arcLeft2 = new DoubleExtension(Math.Atan2(val3.AccurateValue - points[0].Y.AccurateValue, val1.AccurateValue - points[0].X.AccurateValue) + Math.PI / 2.0); DoubleExtension arcRight2 = new DoubleExtension(Math.Atan2(val4.AccurateValue - points[points.Count - 1].Y.AccurateValue, val2.AccurateValue - points[points.Count - 1].X.AccurateValue) + Math.PI / 2.0); subValLeftX = new DoubleExtension(Math.Cos(arcLeft2.AccurateValue)); subValLeftY = new DoubleExtension(Math.Sin(arcLeft2.AccurateValue)); subValRightX = new DoubleExtension(Math.Cos(arcRight2.AccurateValue)); subValRightY = new DoubleExtension(Math.Sin(arcRight2.AccurateValue)); break; } xList = new CubicSplineInterpolationCurveParam(xPointList, subType, subValLeftX, subValRightX); yList = new CubicSplineInterpolationCurveParam(yPointList, subType, subValLeftY, subValRightY); }
public PiecewiseIntervalPolynomialCurveElement DivideByNumber(DoubleExtension val) { List<NormalIntervalPolynomialCurveElement> curve = new List<NormalIntervalPolynomialCurveElement>(); NormalIntervalPolynomialCurveElement item = null; for (int i = 0; i < Curves.Count; i++) { item = Curves[i].DivideByNumber(val); curve.Add(item); } return new PiecewiseIntervalPolynomialCurveElement(curve, Interval); }
public override DataPoint calculatePoint(DoubleExtension doubleExtension) { Debug.Assert(doubleExtension <= interval.RightBorder && doubleExtension >= interval.LeftBorder, "The parameter is out of range for ParametricCubicSplineInterpolationCurve."); return new DataPoint(xCurve.calculate(doubleExtension), yCurve.calculate(doubleExtension)); }
private DoubleExtension calculateBasisFunction(DoubleExtension doubleExtension, int big, int small) { Debug.Assert(doubleExtension <= interval.RightBorder && doubleExtension >= interval.LeftBorder && big >= small, "Invalid argument for BezierCurve.calculateOne()"); return new DoubleExtension(combination[small] * Math.Pow(doubleExtension.AccurateValue, small) * Math.Pow(1 - doubleExtension.AccurateValue, big - small)); }
public abstract DoubleExtension calculate(DoubleExtension doubleExtension);
public static void MiddleBasedResize(DoubleExtension input1, DoubleExtension input2, DoubleExtension multiplier, out DoubleExtension output1, out DoubleExtension output2) { DoubleExtension middle = (input1 + input2) / 2; output1 = middle + (input1 - middle) * multiplier; output2 = middle + (input2 - middle) * multiplier; }
public abstract DataPoint calculatePoint(DoubleExtension doubleExtension);
public int IndexOf(DoubleExtension item) { return sortedPointList.IndexOfKey(item); }
public NormalIntervalPolynomialCurveElement(List<DoubleExtension> coefficients, int degree, DoubleExtension borderVal1, DoubleExtension borderVal2) : this(coefficients, degree, new DataInterval(borderVal1, borderVal2)) { }
public static NormalIntervalPolynomialCurveElement operator -(NormalIntervalPolynomialCurveElement c1, NormalIntervalPolynomialCurveElement c2) { if (c2.equalsToZero) return c1; int degree = Math.Max(c1.Degree, c2.Degree); int i = 0; DoubleExtension val1, val2; List<DoubleExtension> coefficients = new List<DoubleExtension>(); while (i++ < degree) { if (i < c1.Degree) { val1 = c1.coefficients[i]; } else { val1 = new DoubleExtension(0); } if (i < c2.Degree) { val2 = c2.coefficients[i]; } else { val2 = new DoubleExtension(0); } coefficients.Add(val1 - val2); } return new NormalIntervalPolynomialCurveElement(coefficients, degree, DataInterval.Intersection(c1.Interval, c2.Interval)); }
public override DoubleExtension calculate(DoubleExtension doubleExtension) { if (!interval.IsBetweenBordersCloseInterval(doubleExtension)) throw new ArgumentOutOfRangeException("doubleExtension", "The value given is out of borders of intervals. Value: " + doubleExtension.ApproximateString + ", Range: [" + interval.LeftBorder.ApproximateString + ", " + interval.RightBorder.ApproximateString + "]."); DoubleExtension result = new DoubleExtension(0); DoubleExtension poweredX = new DoubleExtension(1); for (int i = 0; i < degree; i++) { result += poweredX * coefficients[i]; poweredX *= doubleExtension.AccurateValue; } return result; }
public PiecewiseIntervalPolynomialCurveElement MultiplyByLinear(DoubleExtension val1, DoubleExtension val0) { List<NormalIntervalPolynomialCurveElement> curve = new List<NormalIntervalPolynomialCurveElement>(); NormalIntervalPolynomialCurveElement item = null; for (int i = 0; i < Curves.Count; i++) { item = Curves[i].MultiplyByLinear(val1, val0); curve.Add(item); } return new PiecewiseIntervalPolynomialCurveElement(curve, Interval); }
public NormalIntervalPolynomialCurveElement MultiplyByLinear(DoubleExtension val1, DoubleExtension val0) { if (EqualsToZero) { return new NormalIntervalPolynomialCurveElement(new DoubleExtension(0), Interval); } List<DoubleExtension> newCoefficients = new List<DoubleExtension>(); for (int i = 0; i < degree; i++) { newCoefficients.Add(coefficients[i] * val0); } if (!(coefficients[degree - 1] * val1).EqualsToZero) { newCoefficients.Add(coefficients[degree - 1] * val1); } if (degree > 1) { for (int i = 1; i < degree; i++) { newCoefficients[i] += coefficients[i - 1] * val1; } } return new NormalIntervalPolynomialCurveElement(newCoefficients, newCoefficients.Count, Interval); }