/// <summary> /// The snap function will transform a curve so that it starts and ends at the control points on either side of it. /// </summary> /// <param name="args">args should have 1 parameter that stores an equation to apply snap to.</param> protected bool HandleSnapFunc(FunctionArgs args, List<double> evaluatedArgs) { if (evaluatedArgs.Count != 1) { return false; } //Get the index of the curve to apply snap to. int curveIndex = GetCurveIndex(); //True if there is a control point before the curve. bool pointBeforeCurveExists = (curveIndex > 0); //True if there is a control point after the curve. bool pointAfterCurveExists = (curveIndex < this.controlPointValues.Count); Expression remainingExpression = args.Parameters[0]; //Store the raw output of the argument. double snapOutputValue = evaluatedArgs[0]; bool errorEncountered = false; ReturnStatus<double> evaluateStatus; //If there is a control point on either side of the equation then snap will need to //modify the output. if (pointBeforeCurveExists || pointAfterCurveExists) { XyPoint<double> pointBeforeCurve = null; XyPoint<double> rawCurveStart = null; XyPoint<double> pointAfterCurve = null; XyPoint<double> rawCurveEnd = null; EvaluationCurveInput endpointInput = (EvaluationCurveInput)this.evalInput.Clone(); //If there is a control point before the equation then we need to evaluate the //equation at this point. if (pointBeforeCurveExists) { pointBeforeCurve = controlPointValues[curveIndex - 1]; endpointInput.setPrimaryInputVal(pointBeforeCurve.X); SetExpressionCurveParameters(endpointInput, remainingExpression); evaluateStatus = EvaluateExpression(remainingExpression); errorEncountered |= !evaluateStatus.IsValid; rawCurveStart = new XyPoint<double>(pointBeforeCurve.X, evaluateStatus.Value); } //If there is a control point after the equation then we need to evaluate the //equation at this point. if (pointAfterCurveExists && errorEncountered == false) { pointAfterCurve = controlPointValues[curveIndex]; endpointInput.setPrimaryInputVal(pointAfterCurve.X); SetExpressionCurveParameters(endpointInput, remainingExpression); evaluateStatus = EvaluateExpression(remainingExpression); errorEncountered |= !evaluateStatus.IsValid; rawCurveEnd = new XyPoint<double>(pointAfterCurve.X, evaluateStatus.Value); } if (errorEncountered == false) { if (pointBeforeCurveExists && pointAfterCurveExists) { snapOutputValue += GetEndPointSnapOffset(pointBeforeCurve.Y, rawCurveStart.Y, pointBeforeCurve.X, pointAfterCurve.X, this.evalInput.getPrimaryInputVal()); snapOutputValue += GetEndPointSnapOffset(pointAfterCurve.Y, rawCurveEnd.Y, pointAfterCurve.X, pointBeforeCurve.X, this.evalInput.getPrimaryInputVal()); } else if (pointBeforeCurveExists) { double yOffset = pointBeforeCurve.Y - rawCurveStart.Y; snapOutputValue += yOffset; } else //pointAfterCurveExists { Debug.Assert(pointAfterCurveExists); double yOffset = pointAfterCurve.Y - rawCurveEnd.Y; snapOutputValue += yOffset; } } } if (errorEncountered) { return false; } else { args.Result = snapOutputValue; return true; } }
/// <summary> /// The snap function will transform a curve so that it starts and ends at the control points on either side of it. /// </summary> /// <param name="args">args should have 1 parameter that stores an equation to apply snap to.</param> protected bool HandleSnapFunc(FunctionArgs args, List <double> evaluatedArgs) { if (evaluatedArgs.Count != 1) { return(false); } //Get the index of the curve to apply snap to. int curveIndex = GetCurveIndex(); //True if there is a control point before the curve. bool pointBeforeCurveExists = (curveIndex > 0); //True if there is a control point after the curve. bool pointAfterCurveExists = (curveIndex < this.controlPointValues.Count); Expression remainingExpression = args.Parameters[0]; //Store the raw output of the argument. double snapOutputValue = evaluatedArgs[0]; bool errorEncountered = false; ReturnStatus <double> evaluateStatus; //If there is a control point on either side of the equation then snap will need to //modify the output. if (pointBeforeCurveExists || pointAfterCurveExists) { XyPoint <double> pointBeforeCurve = null; XyPoint <double> rawCurveStart = null; XyPoint <double> pointAfterCurve = null; XyPoint <double> rawCurveEnd = null; EvaluationCurveInput endpointInput = (EvaluationCurveInput)this.evalInput.Clone(); //If there is a control point before the equation then we need to evaluate the //equation at this point. if (pointBeforeCurveExists) { pointBeforeCurve = controlPointValues[curveIndex - 1]; endpointInput.setPrimaryInputVal(pointBeforeCurve.X); SetExpressionCurveParameters(endpointInput, remainingExpression); evaluateStatus = EvaluateExpression(remainingExpression); errorEncountered |= !evaluateStatus.IsValid; rawCurveStart = new XyPoint <double>(pointBeforeCurve.X, evaluateStatus.Value); } //If there is a control point after the equation then we need to evaluate the //equation at this point. if (pointAfterCurveExists && errorEncountered == false) { pointAfterCurve = controlPointValues[curveIndex]; endpointInput.setPrimaryInputVal(pointAfterCurve.X); SetExpressionCurveParameters(endpointInput, remainingExpression); evaluateStatus = EvaluateExpression(remainingExpression); errorEncountered |= !evaluateStatus.IsValid; rawCurveEnd = new XyPoint <double>(pointAfterCurve.X, evaluateStatus.Value); } if (errorEncountered == false) { if (pointBeforeCurveExists && pointAfterCurveExists) { snapOutputValue += GetEndPointSnapOffset(pointBeforeCurve.Y, rawCurveStart.Y, pointBeforeCurve.X, pointAfterCurve.X, this.evalInput.getPrimaryInputVal()); snapOutputValue += GetEndPointSnapOffset(pointAfterCurve.Y, rawCurveEnd.Y, pointAfterCurve.X, pointBeforeCurve.X, this.evalInput.getPrimaryInputVal()); } else if (pointBeforeCurveExists) { double yOffset = pointBeforeCurve.Y - rawCurveStart.Y; snapOutputValue += yOffset; } else //pointAfterCurveExists { Debug.Assert(pointAfterCurveExists); double yOffset = pointAfterCurve.Y - rawCurveEnd.Y; snapOutputValue += yOffset; } } } if (errorEncountered) { return(false); } else { args.Result = snapOutputValue; return(true); } }
/// <summary> /// Calculates the X and Y coordinates of each control point and stores them in this.controlPointValues /// </summary> /// <param name="erroneousControlPointIndexSet"> /// empty if all points had valid equations. Otherwise contains the index of at least one point with an invalid equation. /// </param> /// <returns>True on success, False if the control point equations could not be evaluated.</returns> protected ReturnStatus <List <XyPoint <double> > > CalculateControlPointValues( List <MssParamInfo> variableParamInfoList, List <MssParamInfo> transformParamInfoList, List <XyPoint <string> > pointEquations, ref HashSet <int> erroneousControlPointIndexSet) { Logger.HighVolume(26, string.Format("CalculateControlPointValues - pointEquations: {0}, transformParamInfoList: {1}", EnumerableUtils.ToString(pointEquations), EnumerableUtils.ToString(transformParamInfoList))); erroneousControlPointIndexSet.Clear(); var controlPointList = new List <XyPoint <double> >(); //Create the input for the control point jobs. The expression string will be //individually set for each equation. EvaluationControlPointInput pointEvalInput = new EvaluationControlPointInput(); pointEvalInput.Init(variableParamInfoList, transformParamInfoList, ""); //Create jobs to evaluate the x and y coordinates for a control point EvaluationControlPointJob pointXEvalJob = new EvaluationControlPointJob(); EvaluationControlPointJob pointYEvalJob = new EvaluationControlPointJob(); double previousPointXVal = 0; //Itterate through each control point equation and evaluate it's X and Y coordinates. for (int i = 0; i < pointEquations.Count; i++) { XyPoint <string> pointEquation = pointEquations[i]; var xEquationStatus = CreateExpressionFromString(pointEquation.X, EvalType.ControlPoint); var yEquationStatus = CreateExpressionFromString(pointEquation.Y, EvalType.ControlPoint); if (!xEquationStatus.IsValid || !yEquationStatus.IsValid) { Logger.HighVolume(27, string.Format("The x or y equation for control point {0} was not a valid equation. Equations: {1}", i, pointEquation)); erroneousControlPointIndexSet.Add(i); return(new ReturnStatus <List <XyPoint <double> > >(controlPointList, false)); } //Evaluate the equation for the current control point's X value pointEvalInput.EquationStr = pointEquation.X; pointXEvalJob.Configure(pointEvalInput, xEquationStatus.Value); pointXEvalJob.Execute(); //Evaluate the equation for the current control point's Y value pointEvalInput.EquationStr = pointEquation.Y; pointYEvalJob.Configure(pointEvalInput, yEquationStatus.Value); pointYEvalJob.Execute(); //If one of the equations could not be evaluated return false if (pointXEvalJob.OutputIsValid == false || pointYEvalJob.OutputIsValid == false) { Logger.HighVolume(28, string.Format("The x or y equation for control point {0} encountered an error while being evaluated. Equations: {1}", i, pointEquation)); erroneousControlPointIndexSet.Add(i); return(new ReturnStatus <List <XyPoint <double> > >(controlPointList, false)); } //Store the current control point's X and Y coordinates in this.controlPointValues. XyPoint <double> curPoint = new XyPoint <double>(pointXEvalJob.OutputVal, pointYEvalJob.OutputVal); controlPointList.Add(curPoint); previousPointXVal = pointXEvalJob.OutputVal; } for (int i = 1; i < controlPointList.Count; i++) { //If the control points are not in order from smallest to largest then return an //invalid return status. if (controlPointList[i - 1].X > controlPointList[i].X) { Logger.HighVolume(29, string.Format("The control points are not in order. X{0}: {1}, X{2}, {3}", i - 1, controlPointList[i - 1].X, i, controlPointList[i].X)); erroneousControlPointIndexSet.Add(i); erroneousControlPointIndexSet.Add(i - 1); return(new ReturnStatus <List <XyPoint <double> > >(controlPointList, false)); } } return(new ReturnStatus <List <XyPoint <double> > >(controlPointList, true)); }
protected ReturnStatus <XyPoint <double> > evaluateCurveAtXVal(double inputXVal, int curveIndex, IMappingEntry mappingEntry, List <MssParamInfo> variableParamInfoList, List <XyPoint <double> > controlPointList) { //For each sample point data1 data2 and data3 will be set to the X value of the //sample point. double relData1 = inputXVal; double relData2 = inputXVal; double relData3 = inputXVal; IStaticMssMsgInfo inMsgInfo = Factory_StaticMssMsgInfo.Create(mappingEntry.InMssMsgRange.MsgType); //If curXVal is outside of the relative input range for data 1 then set //relData1 to NaN double max = (double)inMsgInfo.MaxData1Value; double min = (double)inMsgInfo.MinData1Value; double bottom = (double)mappingEntry.InMssMsgRange.Data1RangeBottom; double top = (double)mappingEntry.InMssMsgRange.Data1RangeTop; if (inputXVal < ((bottom - min) / (max - min + 1)) || inputXVal > ((top - min) / (max - min + 1))) { relData1 = double.NaN; } //If curXVal is outside of the relative input range for data 2 then set relData2 //to NaN max = (double)inMsgInfo.MaxData2Value; min = (double)inMsgInfo.MinData2Value; bottom = (double)mappingEntry.InMssMsgRange.Data2RangeBottom; top = (double)mappingEntry.InMssMsgRange.Data2RangeTop; if (inputXVal < ((bottom - min) / (max - min + 1)) || inputXVal > ((top - min) / (max - min + 1))) { relData2 = double.NaN; } var evalInput = new EvaluationCurveInput(); evalInput.Init( relData1, relData2, relData3, variableParamInfoList, mappingEntry); var evalJob = new EvaluationCurveJob(); var returnedExpression = CreateExpressionFromString(mappingEntry.CurveShapeInfo.CurveEquations[curveIndex], EvalType.Curve); if (returnedExpression.IsValid == false) { return(new ReturnStatus <XyPoint <double> >()); } evalJob.Configure(evalInput, controlPointList, returnedExpression.Value); evalJob.Execute(); if (evalJob.OutputIsValid) { var curPoint = new XyPoint <double>(inputXVal, evalJob.OutputVal); return(new ReturnStatus <XyPoint <double> >(curPoint)); } else { return(new ReturnStatus <XyPoint <double> >()); } }
protected ReturnStatus<XyPoint<double>> evaluateCurveAtXVal(double inputXVal, int curveIndex, IMappingEntry mappingEntry, List<MssParamInfo> variableParamInfoList, List<XyPoint<double>> controlPointList) { //For each sample point data1 data2 and data3 will be set to the X value of the //sample point. double relData1 = inputXVal; double relData2 = inputXVal; double relData3 = inputXVal; IStaticMssMsgInfo inMsgInfo = Factory_StaticMssMsgInfo.Create(mappingEntry.InMssMsgRange.MsgType); //If curXVal is outside of the relative input range for data 1 then set //relData1 to NaN double max = (double)inMsgInfo.MaxData1Value; double min = (double)inMsgInfo.MinData1Value; double bottom = (double)mappingEntry.InMssMsgRange.Data1RangeBottom; double top = (double)mappingEntry.InMssMsgRange.Data1RangeTop; if (inputXVal < ((bottom - min) / (max - min + 1)) || inputXVal > ((top - min) / (max - min + 1))) { relData1 = double.NaN; } //If curXVal is outside of the relative input range for data 2 then set relData2 //to NaN max = (double)inMsgInfo.MaxData2Value; min = (double)inMsgInfo.MinData2Value; bottom = (double)mappingEntry.InMssMsgRange.Data2RangeBottom; top = (double)mappingEntry.InMssMsgRange.Data2RangeTop; if (inputXVal < ((bottom - min) / (max - min + 1)) || inputXVal > ((top - min) / (max - min + 1))) { relData2 = double.NaN; } var evalInput = new EvaluationCurveInput(); evalInput.Init( relData1, relData2, relData3, variableParamInfoList, mappingEntry); var evalJob = new EvaluationCurveJob(); var returnedExpression = CreateExpressionFromString(mappingEntry.CurveShapeInfo.CurveEquations[curveIndex], EvalType.Curve); if (returnedExpression.IsValid == false) { return new ReturnStatus<XyPoint<double>>(); } evalJob.Configure(evalInput, controlPointList, returnedExpression.Value); evalJob.Execute(); if (evalJob.OutputIsValid) { var curPoint = new XyPoint<double>(inputXVal, evalJob.OutputVal); return new ReturnStatus<XyPoint<double>>(curPoint); } else { return new ReturnStatus<XyPoint<double>>(); } }
/// <summary> /// Calculates the X and Y coordinates of each control point and stores them in this.controlPointValues /// </summary> /// <param name="erroneousControlPointIndexSet"> /// empty if all points had valid equations. Otherwise contains the index of at least one point with an invalid equation. /// </param> /// <returns>True on success, False if the control point equations could not be evaluated.</returns> protected ReturnStatus<List<XyPoint<double>>> CalculateControlPointValues( List<MssParamInfo> variableParamInfoList, List<MssParamInfo> transformParamInfoList, List<XyPoint<string>> pointEquations, ref HashSet<int> erroneousControlPointIndexSet) { Logger.HighVolume(26, string.Format("CalculateControlPointValues - pointEquations: {0}, transformParamInfoList: {1}", EnumerableUtils.ToString(pointEquations), EnumerableUtils.ToString(transformParamInfoList))); erroneousControlPointIndexSet.Clear(); var controlPointList = new List<XyPoint<double>>(); //Create the input for the control point jobs. The expression string will be //individually set for each equation. EvaluationControlPointInput pointEvalInput = new EvaluationControlPointInput(); pointEvalInput.Init(variableParamInfoList, transformParamInfoList, ""); //Create jobs to evaluate the x and y coordinates for a control point EvaluationControlPointJob pointXEvalJob = new EvaluationControlPointJob(); EvaluationControlPointJob pointYEvalJob = new EvaluationControlPointJob(); double previousPointXVal = 0; //Itterate through each control point equation and evaluate it's X and Y coordinates. for (int i = 0; i < pointEquations.Count; i++) { XyPoint<string> pointEquation = pointEquations[i]; var xEquationStatus = CreateExpressionFromString(pointEquation.X, EvalType.ControlPoint); var yEquationStatus = CreateExpressionFromString(pointEquation.Y, EvalType.ControlPoint); if (!xEquationStatus.IsValid || !yEquationStatus.IsValid) { Logger.HighVolume(27, string.Format("The x or y equation for control point {0} was not a valid equation. Equations: {1}", i, pointEquation)); erroneousControlPointIndexSet.Add(i); return new ReturnStatus<List<XyPoint<double>>>(controlPointList, false); } //Evaluate the equation for the current control point's X value pointEvalInput.EquationStr = pointEquation.X; pointXEvalJob.Configure(pointEvalInput, xEquationStatus.Value); pointXEvalJob.Execute(); //Evaluate the equation for the current control point's Y value pointEvalInput.EquationStr = pointEquation.Y; pointYEvalJob.Configure(pointEvalInput, yEquationStatus.Value); pointYEvalJob.Execute(); //If one of the equations could not be evaluated return false if (pointXEvalJob.OutputIsValid == false || pointYEvalJob.OutputIsValid == false) { Logger.HighVolume(28, string.Format("The x or y equation for control point {0} encountered an error while being evaluated. Equations: {1}", i, pointEquation)); erroneousControlPointIndexSet.Add(i); return new ReturnStatus<List<XyPoint<double>>>(controlPointList, false); } //Store the current control point's X and Y coordinates in this.controlPointValues. XyPoint<double> curPoint = new XyPoint<double>(pointXEvalJob.OutputVal, pointYEvalJob.OutputVal); controlPointList.Add(curPoint); previousPointXVal = pointXEvalJob.OutputVal; } for (int i = 1; i < controlPointList.Count; i++) { //If the control points are not in order from smallest to largest then return an //invalid return status. if (controlPointList[i - 1].X > controlPointList[i].X) { Logger.HighVolume(29, string.Format("The control points are not in order. X{0}: {1}, X{2}, {3}", i - 1, controlPointList[i - 1].X, i, controlPointList[i].X)); erroneousControlPointIndexSet.Add(i); erroneousControlPointIndexSet.Add(i - 1); return new ReturnStatus<List<XyPoint<double>>>(controlPointList, false); } } return new ReturnStatus<List<XyPoint<double>>>(controlPointList, true); }