public static DenseVector Normalize0to1(this DenseVector data) { var d = new DenseVector(data); var result = new DenseVector(d.Count); d.CopyTo(result); return((DenseVector)(result - d.Min()) / (d.Max() - d.Min())); }
public static double[] NormalizeNeg1to1(this double[] data) { var d = new DenseVector(data); var result = new DenseVector(d.Count); d.CopyTo(result); result = (DenseVector)(result - ((d.Max() + d.Min()) / 2)) / ((d.Max() - d.Min()) / 2); return(result.ToArray()); }
public static double[] Normalize0to1(this double[] data) { var returnData = new double[data.Length]; var d = new DenseVector(data); var result = new DenseVector(d.Count); d.CopyTo(result); result = (DenseVector)(result - d.Min()) / (d.Max() - d.Min()); return(result.ToArray()); }
private void CheckIfIsExtremum(DenseVector vector) { double actualMin = vector.Min(); if (actualMin < MinValue) { MinValue = actualMin; } double actualMax = vector.Max(); if (actualMax > MaxValue) { MaxValue = actualMax; } }
public void Represent() { if ((dvScatterXSpace != null) && (dvScatterFuncValues != null)) { if (theRepresentingFunctions.Count > 0) { if (ForceFuncLimits) { double ySpaceGap = 0.2d * (ForcedFuncMaxValue - ForcedFuncMinValue); overallFuncMax = ForcedFuncMaxValue + ySpaceGap; overallFuncMin = ForcedFuncMinValue - ySpaceGap; } else { double ySpaceGap = 0.2d * (dvScatterFuncValues.Max() - dvScatterFuncValues.Min()); overallFuncMax = ((dvScatterFuncValues.Max() + ySpaceGap) > overallFuncMax) ? (dvScatterFuncValues.Max() + ySpaceGap) : (overallFuncMax); overallFuncMin = ((dvScatterFuncValues.Min() - ySpaceGap) < overallFuncMin) ? (dvScatterFuncValues.Min() - ySpaceGap) : (overallFuncMin); } //double xSpaceGap = 0.2d * (dvScatterXSpace.Max() - dvScatterXSpace.Min()); //xSpaceMin = ((dvScatterXSpace.Min() - xSpaceGap) < xSpaceMin) // ? (dvScatterXSpace.Min() - xSpaceGap) // : (xSpaceMin); //xSpaceMax = ((dvScatterXSpace.Max() + xSpaceGap) > xSpaceMax) // ? (dvScatterXSpace.Max() + xSpaceGap) // : (xSpaceMax); xSpaceMin = ((dvScatterXSpace.Min()) < xSpaceMin) ? (dvScatterXSpace.Min()) : (xSpaceMin); xSpaceMax = ((dvScatterXSpace.Max()) > xSpaceMax) ? (dvScatterXSpace.Max()) : (xSpaceMax); } else { if (ForceFuncLimits) { double ySpaceGap = 0.2d * (ForcedFuncMaxValue - ForcedFuncMinValue); overallFuncMax = ForcedFuncMaxValue + ySpaceGap; overallFuncMin = ForcedFuncMinValue - ySpaceGap; } else { double ySpaceGap = 0.2d * (dvScatterFuncValues.Max() - dvScatterFuncValues.Min()); overallFuncMax = dvScatterFuncValues.Max() + ySpaceGap; overallFuncMin = dvScatterFuncValues.Min() - ySpaceGap; } //double xSpaceGap = 0.2d * (dvScatterXSpace.Max() - dvScatterXSpace.Min()); //xSpaceMin = ((dvScatterXSpace.Min() - xSpaceGap) < xSpaceMin) // ? (dvScatterXSpace.Min() - xSpaceGap) // : (xSpaceMin); //xSpaceMax = ((dvScatterXSpace.Max() + xSpaceGap) > xSpaceMax) // ? (dvScatterXSpace.Max() + xSpaceGap) // : (xSpaceMax); xSpaceMin = ((dvScatterXSpace.Min()) < xSpaceMin) ? (dvScatterXSpace.Min()) : (xSpaceMin); xSpaceMax = ((dvScatterXSpace.Max()) > xSpaceMax) ? (dvScatterXSpace.Max()) : (xSpaceMax); } } pictureWidth = pbFunctionRepresentation.Width; pictureHeight = pbFunctionRepresentation.Height; serviceSpaceGap = Convert.ToInt32(0.05d * Math.Min(pictureHeight, pictureWidth)); theImage = new Image <Bgr, Byte>(pictureWidth, pictureHeight, new Bgr(255, 255, 255)); RepresentScatter(); RepresentAnalytic(); }
private void RepresentAnalytic() { int xValuesCount = pictureWidth - (2 * serviceSpaceGap);// оставляем место на шкалу Y List <Point> rulerVertices = new List <Point>(); rulerVertices.Add(new Point(serviceSpaceGap, pictureHeight - serviceSpaceGap)); rulerVertices.Add(new Point(pictureWidth - serviceSpaceGap, pictureHeight - serviceSpaceGap)); rulerVertices.Add(new Point(pictureWidth - serviceSpaceGap, serviceSpaceGap)); rulerVertices.Add(new Point(serviceSpaceGap, serviceSpaceGap)); theImage.DrawPolyline(rulerVertices.ToArray(), true, colorBlack, 2); DenseVector dvXSpaceValues = DenseVector.Create(xValuesCount, new Func <int, double>(i => xSpaceMin + ((double)i / ((double)xValuesCount - 1.0d)) * (xSpaceMax - xSpaceMin))); DenseVector parametersList = null; for (int i = 0; i < theRepresentingFunctions.Count; i++) { Func <DenseVector, double, double> theRepresentingFunction = theRepresentingFunctions[i]; DenseVector currentParametersList = parameters[i]; DenseVector dvFuncValues = DenseVector.Create(xValuesCount, new Func <int, double>(j => theRepresentingFunction(currentParametersList, dvXSpaceValues[j]))); double funcMax = dvFuncValues.Max(); double funcMin = dvFuncValues.Min(); if (!ForceFuncLimits) { overallFuncMax = (funcMax > overallFuncMax) ? (funcMax) : (overallFuncMax); overallFuncMin = (funcMin < overallFuncMin) ? (funcMin) : (overallFuncMin); } } #region Прописываем текстовые маркеры MCvFont theFont = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_PLAIN, 1.0d, 1.0d); theFont.thickness = 1; double dMarkersCount = (double)(pictureHeight - (2 * serviceSpaceGap)) / 30.0d; dMarkersCount = (dMarkersCount > 10.0d) ? (10.0d) : (dMarkersCount); double dRulerValueGap = (overallFuncMax - overallFuncMin) / (double)dMarkersCount; //dRulerValueGap = (dRulerValueGap < 1.0d) ? (1.0d) : dRulerValueGap; int deciGap = Convert.ToInt32(Math.Truncate(Math.Log(dRulerValueGap, 2.0d))); double rulerValueGap = Math.Pow(2.0, (double)deciGap); double lowerMarkerValue = overallFuncMin - Math.IEEERemainder(overallFuncMin, rulerValueGap); lowerMarkerValue = (lowerMarkerValue < overallFuncMin) ? (lowerMarkerValue + rulerValueGap) : (lowerMarkerValue); double currentMarkerValue = lowerMarkerValue; double nextYPositionDouble = (1.0d - ((currentMarkerValue - overallFuncMin) / (overallFuncMax - overallFuncMin))) * (double)(pictureHeight - 2 * serviceSpaceGap) + serviceSpaceGap; while (nextYPositionDouble > serviceSpaceGap) { double yPositionDouble = (1.0d - ((currentMarkerValue - overallFuncMin) / (overallFuncMax - overallFuncMin))) * (double)(pictureHeight - 2 * serviceSpaceGap) + serviceSpaceGap; int yPosition = Convert.ToInt32(Math.Round(yPositionDouble)); LineSegment2D theLine = new LineSegment2D(new Point(serviceSpaceGap, yPosition), new Point(serviceSpaceGap - 5, yPosition)); Bgr markerColor = colorBlack; theImage.Draw(theLine, markerColor, 2); String message = currentMarkerValue.ToString(); //theImage.Draw(message, new Point(2, yPosition), Emgu.CV.CvEnum.FontFace.HersheyPlain, 1.0d, markerColor); theImage.Draw(message, ref theFont, new Point(2, yPosition), markerColor); currentMarkerValue += rulerValueGap; nextYPositionDouble = (1.0d - ((currentMarkerValue - overallFuncMin) / (overallFuncMax - overallFuncMin))) * (double)(pictureHeight - 2 * serviceSpaceGap) + serviceSpaceGap; } double dMarkersCountX = (double)(pictureWidth - (2 * serviceSpaceGap)) / 30.0d; dMarkersCountX = (dMarkersCountX > 10.0d) ? (10.0d) : (dMarkersCountX); double dRulerValueGapX = (xSpaceMax - xSpaceMin) / (double)dMarkersCountX; int deciGapX = Convert.ToInt32(Math.Truncate(Math.Log(dRulerValueGapX, 2.0d))); double rulerValueGapX = Math.Pow(2.0, (double)deciGapX); double lowerMarkerValueX = xSpaceMin - Math.IEEERemainder(xSpaceMin, rulerValueGapX); lowerMarkerValueX = (lowerMarkerValueX < xSpaceMin) ? (lowerMarkerValueX + rulerValueGapX) : (lowerMarkerValueX); double currentMarkerValueX = lowerMarkerValueX; double nextXPositionDouble = serviceSpaceGap + ((currentMarkerValueX - xSpaceMin) / (xSpaceMax - xSpaceMin)) * (double)(pictureWidth - 2 * serviceSpaceGap); while (nextXPositionDouble < pictureWidth - serviceSpaceGap) { double xPositionDouble = serviceSpaceGap + ((currentMarkerValueX - xSpaceMin) / (xSpaceMax - xSpaceMin)) * (double)(pictureWidth - 2 * serviceSpaceGap); int xPosition = Convert.ToInt32(Math.Round(xPositionDouble)); LineSegment2D theLine = new LineSegment2D(new Point(xPosition, pictureHeight - serviceSpaceGap), new Point(xPosition, pictureHeight - serviceSpaceGap + 5)); Bgr markerColor = colorBlack; theImage.Draw(theLine, markerColor, 2); String message = currentMarkerValueX.ToString(); theImage.Draw(message, ref theFont, new Point(xPosition, pictureHeight - 10), markerColor); // theImage.Draw(message, new Point(xPosition, pictureHeight - 10), Emgu.CV.CvEnum.FontFace.HersheyPlain, 1.0d, markerColor); currentMarkerValueX += rulerValueGapX; nextXPositionDouble = serviceSpaceGap + ((currentMarkerValueX - xSpaceMin) / (xSpaceMax - xSpaceMin)) * (double)(pictureWidth - 2 * serviceSpaceGap); } #endregion Прописываем текстовые маркеры double koeff = (pictureHeight - (2 * serviceSpaceGap)) / (overallFuncMax - overallFuncMin); for (int i = 0; i < theRepresentingFunctions.Count; i++) { Func <DenseVector, double, double> theRepresentingFunction = theRepresentingFunctions[i]; DenseVector currentParametersList = parameters[i]; double currFuncKoeff = koeff; if (scaleFunctionValuesToMax[i]) { DenseVector dvCurrFuncValues = DenseVector.Create(xValuesCount, j => theRepresentingFunction(currentParametersList, dvXSpaceValues[j])); double currFuncMax = dvCurrFuncValues.Max(); double currFuncMin = dvCurrFuncValues.Min(); currFuncKoeff = (pictureHeight - (2 * serviceSpaceGap)) / (currFuncMax - currFuncMin); } //DenseVector dvXSpaceValues = DenseVector.Create(xValuesCount, new Func<int, double>(i => xSpaceMin + ((double)i / ((double)xValuesCount - 1.0d)) * (xSpaceMax - xSpaceMin))); parametersList = null; DenseVector dvFuncValues = DenseVector.Create(xValuesCount, new Func <int, double>(j => theRepresentingFunction(currentParametersList, dvXSpaceValues[j]))); Bgr currentLineColor = lineColors[i]; DenseVector xCoordinates = DenseVector.Create(xValuesCount, new Func <int, double>(j => ((double)serviceSpaceGap + j))); DenseVector yCoordinates = DenseVector.Create(xValuesCount, new Func <int, double>(j => { double pixValue = currFuncKoeff * (dvFuncValues[j] - overallFuncMin); return(pictureHeight - serviceSpaceGap - pixValue); })); List <Point> funcRepresentationPoints = new List <Point>(); for (int j = 0; j < xValuesCount; j++) { if (double.IsNaN(yCoordinates[j])) { continue; } funcRepresentationPoints.Add(new Point(Convert.ToInt32(xCoordinates[j]), Convert.ToInt32(yCoordinates[j]))); } theImage.DrawPolyline(funcRepresentationPoints.ToArray(), false, currentLineColor, 2); } ThreadSafeOperations.UpdatePictureBox(pbFunctionRepresentation, theImage.Bitmap, false); }
private Image <Bgr, byte> FillGraphImage(Size imgSize) { string curDirPath = Directory.GetCurrentDirectory() + "\\logs\\"; DirectoryInfo dirInfo = new DirectoryInfo(curDirPath); List <Dictionary <string, object> > lReadData = new List <Dictionary <string, object> >(); if (defaultGraphsTimeSpan) { graphsTimeSpan = new Tuple <DateTime, DateTime>(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow); } GraphVariablesTypes currVarType = GraphVariablesTypes.none; if (rbtnPressureGraph.Checked) { currVarType = GraphVariablesTypes.Pressure; } if (rbtnAirTempGraph.Checked) { currVarType = GraphVariablesTypes.AirTemp; } if (rbtnWaterTempGraph.Checked) { currVarType = GraphVariablesTypes.WaterTemp; } if (rbtnWindSpeedGraph.Checked) { currVarType = GraphVariablesTypes.WindSpeed; } if ((fRenderer == null) || (!prevGraphsTimeSpan.Equals(graphsTimeSpan) || currVarType != prevGraphVariable)) { fRenderer = new MultipleScatterAndFunctionsRepresentation(imgSize); switch (currVarType) { case GraphVariablesTypes.Pressure: { currValueColor = new Bgr(Color.Blue); break; } case GraphVariablesTypes.AirTemp: { currValueColor = new Bgr(Color.Red); break; } case GraphVariablesTypes.WaterTemp: { currValueColor = new Bgr(Color.RoyalBlue); break; } case GraphVariablesTypes.WindSpeed: { currValueColor = new Bgr(Color.Gray); break; } default: { currValueColor = new Bgr(Color.Blue); break; } } } else if (fRenderer != null) { if (fRenderer.TheImage.Size != imgSize) { fRenderer.ResizeCanvas(imgSize); } } if (!prevGraphsTimeSpan.Equals(graphsTimeSpan)) { IEnumerable <string> ncFileNames = Directory.EnumerateFiles(curDirPath, "IoffeVesselInfoStream-MeteoDataLog-*.nc", SearchOption.TopDirectoryOnly); foreach (string ncFileName in ncFileNames) { Tuple <DateTime, DateTime> currFileDateTimeRange = null; try { currFileDateTimeRange = ServiceTools.GetNetCDFfileTimeStampsRange(ncFileName); } catch (Exception ex) { #region report #if DEBUG ServiceTools.ExecMethodInSeparateThread(this, () => { theLogWindow = ServiceTools.LogAText(theLogWindow, "an exception has been thrown during file reading: " + Environment.NewLine + ncFileName + Environment.NewLine + "message: " + ex.Message + Environment.NewLine + ServiceTools.CurrentCodeLineDescription()); }); #else ServiceTools.ExecMethodInSeparateThread(this, () => { ServiceTools.logToTextFile(errorLogFilename, "an exception has been thrown during file reading: " + Environment.NewLine + ncFileName + Environment.NewLine + "message: " + ex.Message + Environment.NewLine + ServiceTools.CurrentCodeLineDescription(), true, true); }); #endif #endregion report } if (currFileDateTimeRange == null) { continue; } if ((currFileDateTimeRange.Item1 >= graphsTimeSpan.Item1) && (currFileDateTimeRange.Item1 <= graphsTimeSpan.Item2) || (currFileDateTimeRange.Item2 >= graphsTimeSpan.Item1) && (currFileDateTimeRange.Item2 <= graphsTimeSpan.Item2)) { Dictionary <string, object> dictFileData = null; try { dictFileData = NetCDFoperations.ReadDataFromFile(ncFileName); } catch (Exception ex) { #region report #if DEBUG ServiceTools.ExecMethodInSeparateThread(this, () => { theLogWindow = ServiceTools.LogAText(theLogWindow, "an exception has been thrown during file reading: " + Environment.NewLine + ncFileName + Environment.NewLine + "message: " + ex.Message + Environment.NewLine + ServiceTools.CurrentCodeLineDescription()); }); #else ServiceTools.ExecMethodInSeparateThread(this, () => { ServiceTools.logToTextFile(errorLogFilename, "an exception has been thrown during file reading: " + Environment.NewLine + ncFileName + Environment.NewLine + "message: " + ex.Message + Environment.NewLine + ServiceTools.CurrentCodeLineDescription(), true, true); }); #endif #endregion report } if (dictFileData != null) { lReadData.Add(dictFileData); } } } foreach (Dictionary <string, object> currFileDataDict in lReadData) { if (currFileDataDict == null) { continue; } string varNameDateTime = "DateTime"; List <long> currFileDateTimeLongTicksList = new List <long>((currFileDataDict[varNameDateTime] as long[])); List <DateTime> currFileDateTimeList = currFileDateTimeLongTicksList.ConvertAll(longVal => new DateTime(longVal)); string varNameMeteoData = "MeteoData"; List <MeteoData> currFileMeteoDataList = MeteoData.OfDenseMatrix(currFileDataDict[varNameMeteoData] as DenseMatrix); if (tsMeteoDataForGraphs == null) { try { tsMeteoDataForGraphs = new TimeSeries <MeteoData>(currFileMeteoDataList, currFileDateTimeList, true); } catch (Exception ex) { #region report #if DEBUG ServiceTools.ExecMethodInSeparateThread(this, () => { theLogWindow = ServiceTools.LogAText(theLogWindow, "couldn`t create timeseries: exception has been thrown" + Environment.NewLine + ServiceTools.CurrentCodeLineDescription() + Environment.NewLine + "message: " + ex.Message); }); #else ServiceTools.ExecMethodInSeparateThread(this, () => { ServiceTools.logToTextFile(errorLogFilename, "couldn`t create timeseries: exception has been thrown" + Environment.NewLine + ServiceTools.CurrentCodeLineDescription() + Environment.NewLine + "message: " + ex.Message, true, true); }); #endif #endregion report } } else { try { tsMeteoDataForGraphs.AddSubseriaData(currFileMeteoDataList, currFileDateTimeList, true); } catch (Exception ex) { #region report #if DEBUG ServiceTools.ExecMethodInSeparateThread(this, () => { theLogWindow = ServiceTools.LogAText(theLogWindow, "couldn`t create timeseries: exception has been thrown" + Environment.NewLine + ServiceTools.CurrentCodeLineDescription() + Environment.NewLine + "message: " + ex.Message); }); #else ServiceTools.ExecMethodInSeparateThread(this, () => { ServiceTools.logToTextFile(errorLogFilename, "couldn`t create timeseries: exception has been thrown" + Environment.NewLine + ServiceTools.CurrentCodeLineDescription() + Environment.NewLine + "message: " + ex.Message, true, true); }); #endif #endregion report } } } if (tsMeteoDataForGraphs == null) { return(null); } tsMeteoDataForGraphs.SortByTimeStamps(); tsMeteoDataForGraphs.RemoveDuplicatedTimeStamps(); DateTime utcNow = DateTime.UtcNow; if (defaultGraphsTimeSpan) { tsMeteoDataForGraphs.RemoveValues(dt => (utcNow - dt).TotalSeconds > 86400); } else { tsMeteoDataForGraphs.RemoveValues( dt => !((dt >= graphsTimeSpan.Item1) && (dt <= graphsTimeSpan.Item2))); } List <TimeSeries <MeteoData> > subSeriesBy1Minute = tsMeteoDataForGraphs.SplitByTimeSpan(new TimeSpan(0, 1, 0)); List <double> lSubSeriesEntriesCount = subSeriesBy1Minute.ConvertAll(subs => (double)subs.Count); DescriptiveStatistics statsCounts = new DescriptiveStatistics(lSubSeriesEntriesCount); aveMinuteEntriesCount = Convert.ToInt32(statsCounts.Mean); // = tsMeteoData.TimeStamps.ConvertAll(dt => (dt - maxDateTime).TotalSeconds); } List <MeteoData> meteoDataList = tsMeteoDataForGraphs.DataValues; DateTime maxDateTime = tsMeteoDataForGraphs.TimeStamps.Max(); if ((currVarType != prevGraphVariable) || !prevGraphsTimeSpan.Equals(graphsTimeSpan)) { double minVarValue = 0.0d; double maxVarValue = 1.0d; List <double> currVarToShowValues = new List <double>(); switch (currVarType) { case GraphVariablesTypes.Pressure: { currVarToShowValues = meteoDataList.ConvertAll(mdt => mdt.pressure); TimeSeries <double> currVarTS = new TimeSeries <double>(currVarToShowValues, tsMeteoDataForGraphs.TimeStamps); currVarTS.RemoveValues(dVal => dVal <= 900.0d); currVarToShowValues = new List <double>(currVarTS.DataValues); currFileSecondsList = currVarTS.TimeStamps.ConvertAll(dt => (dt - maxDateTime).TotalSeconds); fRenderer.yAxisValuesConversionToRepresentTicksValues = new Func <double, string>(dVal => dVal.ToString("F1")); break; } case GraphVariablesTypes.AirTemp: { currVarToShowValues = meteoDataList.ConvertAll(mdt => mdt.airTemperature); TimeSeries <double> currVarTS = new TimeSeries <double>(currVarToShowValues, tsMeteoDataForGraphs.TimeStamps); currVarTS.RemoveValues(dVal => ((dVal < -20.0d) || (dVal > 50.0d))); currVarToShowValues = new List <double>(currVarTS.DataValues); currFileSecondsList = currVarTS.TimeStamps.ConvertAll(dt => (dt - maxDateTime).TotalSeconds); fRenderer.yAxisValuesConversionToRepresentTicksValues = new Func <double, string>(dVal => dVal.ToString("F2")); break; } case GraphVariablesTypes.WaterTemp: { currVarToShowValues = meteoDataList.ConvertAll(mdt => mdt.waterTemperature); TimeSeries <double> currVarTS = new TimeSeries <double>(currVarToShowValues, tsMeteoDataForGraphs.TimeStamps); currVarTS.RemoveValues(dVal => ((dVal < -20.0d) || (dVal > 50.0d))); currVarToShowValues = new List <double>(currVarTS.DataValues); currFileSecondsList = currVarTS.TimeStamps.ConvertAll(dt => (dt - maxDateTime).TotalSeconds); fRenderer.yAxisValuesConversionToRepresentTicksValues = new Func <double, string>(dVal => dVal.ToString("F2")); break; } case GraphVariablesTypes.WindSpeed: { currVarToShowValues = meteoDataList.ConvertAll(mdt => mdt.windSpeed); TimeSeries <double> currVarTS = new TimeSeries <double>(currVarToShowValues, tsMeteoDataForGraphs.TimeStamps); currVarTS.RemoveValues(dVal => ((dVal < 0.0d) || (dVal > 50.0d))); currVarToShowValues = new List <double>(currVarTS.DataValues); currFileSecondsList = currVarTS.TimeStamps.ConvertAll(dt => (dt - maxDateTime).TotalSeconds); fRenderer.yAxisValuesConversionToRepresentTicksValues = new Func <double, string>(dVal => dVal.ToString("F1")); break; } default: return(null); } dvVarValues = DenseVector.OfEnumerable(currVarToShowValues); dvVarValues = dvVarValues.Conv(Extensions.StandardConvolutionKernels.gauss, aveMinuteEntriesCount * 10); } fRenderer.dvScatterFuncValues.Add(dvVarValues); fRenderer.dvScatterXSpace.Add(DenseVector.OfEnumerable(currFileSecondsList)); fRenderer.xAxisValuesConversionToRepresentTicksValues = (dValSec) => { DateTime currDT = tsMeteoDataForGraphs.TimeStamps.Max().AddSeconds(dValSec); return(currDT.ToString("yyyy-MM-dd" + Environment.NewLine + "HH:mm")); }; fRenderer.scatterLineColors.Add(currValueColor); fRenderer.scatterDrawingVariants.Add(SequencesDrawingVariants.polyline); fRenderer.xSpaceMin = currFileSecondsList.Min(); fRenderer.xSpaceMax = currFileSecondsList.Max(); fRenderer.overallFuncMin = dvVarValues.Min(); fRenderer.overallFuncMax = dvVarValues.Max(); fRenderer.fixSpecifiedMargins = true; fRenderer.Represent(); Image <Bgr, byte> retImg = fRenderer.TheImage; // расположим надпись string strSign = "current value: " + dvVarValues.Last().ToString("F2"); List <TextBarImage> textBarsCases = new List <TextBarImage>(); TextBarImage tbimTopLeftSign = new TextBarImage(strSign, retImg); tbimTopLeftSign.PtSurroundingBarStart = new Point(fRenderer.LeftServiceSpaceGapX + tbimTopLeftSign.textHalfHeight, fRenderer.TopServiceSpaceGapY + tbimTopLeftSign.textHalfHeight); textBarsCases.Add(tbimTopLeftSign); TextBarImage tbimBtmLeftSign = new TextBarImage(strSign, retImg); tbimBtmLeftSign.PtSurroundingBarStart = new Point(fRenderer.LeftServiceSpaceGapX + tbimBtmLeftSign.textHalfHeight, retImg.Height - fRenderer.BtmServiceSpaceGapY - tbimBtmLeftSign.textHalfHeight - tbimBtmLeftSign.textHeight * 2); textBarsCases.Add(tbimBtmLeftSign); TextBarImage tbimTopRightSign = new TextBarImage(strSign, retImg); tbimTopRightSign.PtSurroundingBarStart = new Point( retImg.Width - fRenderer.RightServiceSpaceGapX - tbimTopRightSign.textHalfHeight - tbimTopRightSign.textBarSize.Width, fRenderer.TopServiceSpaceGapY + tbimTopLeftSign.textHalfHeight); textBarsCases.Add(tbimTopRightSign); TextBarImage tbimBtmRightSign = new TextBarImage(strSign, retImg); tbimBtmRightSign.PtSurroundingBarStart = new Point( retImg.Width - fRenderer.RightServiceSpaceGapX - tbimBtmRightSign.textHalfHeight - tbimBtmRightSign.textBarSize.Width, retImg.Height - fRenderer.BtmServiceSpaceGapY - tbimBtmRightSign.textHalfHeight - tbimBtmRightSign.textHeight * 2); textBarsCases.Add(tbimBtmRightSign); textBarsCases.Sort((case1, case2) => (case1.SubImageInTextRect.CountNonzero().Sum() > case2.SubImageInTextRect.CountNonzero().Sum()) ? 1 : -1); MCvFont theFont = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_PLAIN, 2.0d, 2.0d) { thickness = 2, }; // retImg.Draw(strSign, textBarsCases[0].ptTextBaselineStart, Emgu.CV.CvEnum.FontFace.HersheyPlain, 2.0d, new Bgr(Color.Green), 2); retImg.Draw(strSign, ref theFont, textBarsCases[0].ptTextBaselineStart, new Bgr(Color.Green)); retImg.Draw(textBarsCases[0].rectSurroundingBar, new Bgr(Color.Green), 2); prevGraphsTimeSpan = graphsTimeSpan; prevGraphVariable = currVarType; return(retImg); }
private void RepresentAnalytic() { #region Прописываем текстовые маркеры #region Y //MCvFont theFont = new MCvFont(FONT.CV_FONT_HERSHEY_PLAIN, 1.0d, 1.0d); //theFont.thickness = 1; // замерим высоту подписей по X по значению в минимуме string strMinXvalueMarker = (xAxisValuesConversionToRepresentTicksValues == null)?(xSpaceMin.ToString()) :(xAxisValuesConversionToRepresentTicksValues(xSpaceMin)); TextBarImage minXvalueMarkerTextBar = new TextBarImage(strMinXvalueMarker, new Image <Bgr, byte>(new Size(pictureWidth, pictureHeight))); int barHeight = minXvalueMarkerTextBar.textBarSize.Height; if (btmServiceSpaceGapY < 1.5 * barHeight) { btmServiceSpaceGapY = Convert.ToInt32(1.5 * barHeight); } double dMarkersCount = (double)(pictureHeight - (btmServiceSpaceGapY + topServiceSpaceGapY)) / 30.0d; dMarkersCount = (dMarkersCount > 10.0d) ? (10.0d) : (dMarkersCount); double dRulerValueGap = (overallFuncMax - overallFuncMin) / (double)dMarkersCount; //dRulerValueGap = (dRulerValueGap < 1.0d) ? (1.0d) : dRulerValueGap; int deciGap = Convert.ToInt32(Math.Truncate(Math.Log(dRulerValueGap, 2.0d))); double rulerValueGap = Math.Pow(2.0, (double)deciGap); double lowerMarkerValue = overallFuncMin - overallFuncMin % rulerValueGap;// Math.IEEERemainder(overallFuncMin, rulerValueGap); lowerMarkerValue = (lowerMarkerValue < overallFuncMin) ? (lowerMarkerValue + rulerValueGap) : (lowerMarkerValue); List <double> yMarkersValues = new List <double>(); yMarkersValues.Add(lowerMarkerValue); double currentMarkerValue = lowerMarkerValue; while (currentMarkerValue <= overallFuncMax) { currentMarkerValue += rulerValueGap; yMarkersValues.Add(currentMarkerValue); } List <TextBarImage> lTextBars = new List <TextBarImage>(); foreach (double markerValue in yMarkersValues) { string currMarkerPresentation = markerValue.ToString(); if (yAxisValuesConversionToRepresentTicksValues != null) { currMarkerPresentation = yAxisValuesConversionToRepresentTicksValues(markerValue); } TextBarImage currTextBar = new TextBarImage(currMarkerPresentation, new Image <Bgr, byte>(new Size(pictureWidth, pictureHeight))); lTextBars.Add(currTextBar); } int maxYlabelWidth = lTextBars.Max(textBar => textBar.textBarSize.Width); if (leftServiceSpaceGapX < maxYlabelWidth) { leftServiceSpaceGapX = maxYlabelWidth; } currentMarkerValue = lowerMarkerValue; double nextYPositionDouble = (1.0d - ((currentMarkerValue - overallFuncMin) / (overallFuncMax - overallFuncMin))) * (double)(pictureHeight - topServiceSpaceGapY - btmServiceSpaceGapY) + topServiceSpaceGapY; while (nextYPositionDouble > topServiceSpaceGapY) { double yPositionDouble = (1.0d - ((currentMarkerValue - overallFuncMin) / (overallFuncMax - overallFuncMin))) * (double)(pictureHeight - topServiceSpaceGapY - btmServiceSpaceGapY) + topServiceSpaceGapY; int yPosition = Convert.ToInt32(Math.Round(yPositionDouble)); LineSegment2D theLine = new LineSegment2D(new Point(leftServiceSpaceGapX, yPosition), new Point(leftServiceSpaceGapX - 5, yPosition)); Bgr markerColor = colorGreen; theImage.Draw(theLine, markerColor, 2); string currMarkerPresentation = currentMarkerValue.ToString(); if (yAxisValuesConversionToRepresentTicksValues != null) { currMarkerPresentation = yAxisValuesConversionToRepresentTicksValues(currentMarkerValue); } //theImage.Draw(currMarkerPresentation, ref theFont, new Point(2, yPosition), markerColor); TextBarImage currSignImage = new TextBarImage(currMarkerPresentation, theImage); currSignImage.PtSurroundingBarStart = new Point(0, yPosition - currSignImage.textHeight); theImage = theImage.Add(currSignImage.TextSignImageAtOriginalBlank(markerColor)); currentMarkerValue += rulerValueGap; nextYPositionDouble = (1.0d - ((currentMarkerValue - overallFuncMin) / (overallFuncMax - overallFuncMin))) * (double)(pictureHeight - topServiceSpaceGapY - btmServiceSpaceGapY) + topServiceSpaceGapY; } #endregion Y #region X double rulerValueGapX = 0.0d; double lowerMarkerValueX = 0.0d; bool markersCountRight = false; int initialDivider = 30; double dMarkersCountX = (double)(pictureWidth - (leftServiceSpaceGapX + rightServiceSpaceGapX)) / (double)initialDivider; while (!markersCountRight) { dMarkersCountX = (dMarkersCountX > 10.0d) ? (10.0d) : (dMarkersCountX); double dRulerValueGapX = (xSpaceMax - xSpaceMin) / (double)dMarkersCountX; //int deciGapX = Convert.ToInt32(Math.Truncate(Math.Log(dRulerValueGapX, 2.0d))); //rulerValueGapX = Math.Pow(2.0, (double)deciGapX); rulerValueGapX = dRulerValueGapX; lowerMarkerValueX = xSpaceMin - (xSpaceMin % rulerValueGapX); // Math.IEEERemainder(xSpaceMin, rulerValueGapX); lowerMarkerValueX = (lowerMarkerValueX < xSpaceMin) ? (lowerMarkerValueX + rulerValueGapX) : (lowerMarkerValueX); double firstMarkerValueX = lowerMarkerValueX; List <double> xMarkersValues = new List <double>(); xMarkersValues.Add(firstMarkerValueX); currentMarkerValue = firstMarkerValueX; while (currentMarkerValue <= xSpaceMax) { currentMarkerValue += rulerValueGapX; xMarkersValues.Add(currentMarkerValue); } List <TextBarImage> lTextBarsXaxis = new List <TextBarImage>(); foreach (double markerValue in xMarkersValues) { string currMarkerPresentation = markerValue.ToString(); if (xAxisValuesConversionToRepresentTicksValues != null) { currMarkerPresentation = xAxisValuesConversionToRepresentTicksValues(markerValue); } TextBarImage currTextBar = new TextBarImage(currMarkerPresentation, new Image <Bgr, byte>(new Size(pictureWidth, pictureHeight))); lTextBarsXaxis.Add(currTextBar); } int totalTextBarsWidth = lTextBarsXaxis.Sum(textBar => textBar.textBarSize.Width); if (totalTextBarsWidth > pictureWidth - leftServiceSpaceGapX - rightServiceSpaceGapX) { dMarkersCountX = dMarkersCountX - 1.0d; if (dMarkersCountX <= 2) { dMarkersCountX = 2.0d; markersCountRight = true; } } else { markersCountRight = true; } } double currentMarkerValueX = lowerMarkerValueX; double nextXPositionDouble = leftServiceSpaceGapX + ((currentMarkerValueX - xSpaceMin) / (xSpaceMax - xSpaceMin)) * (double)(pictureWidth - leftServiceSpaceGapX - rightServiceSpaceGapX); while (nextXPositionDouble <= pictureWidth - rightServiceSpaceGapX) { double xPositionDouble = leftServiceSpaceGapX + ((currentMarkerValueX - xSpaceMin) / (xSpaceMax - xSpaceMin)) * (double)(pictureWidth - leftServiceSpaceGapX - rightServiceSpaceGapX); int xPosition = Convert.ToInt32(Math.Round(xPositionDouble)); LineSegment2D theLine = new LineSegment2D(new Point(xPosition, pictureHeight - btmServiceSpaceGapY), new Point(xPosition, pictureHeight - btmServiceSpaceGapY + 5)); Bgr markerColor = colorGreen; theImage.Draw(theLine, markerColor, 2); string currMarkerPresentation = currentMarkerValueX.ToString(); if (xAxisValuesConversionToRepresentTicksValues != null) { currMarkerPresentation = xAxisValuesConversionToRepresentTicksValues(currentMarkerValueX); } TextBarImage currSignImage = new TextBarImage(currMarkerPresentation, theImage); currSignImage.PtSurroundingBarStart = new Point(Convert.ToInt32(xPosition - currSignImage.textBarSize.Width / 2), pictureHeight - btmServiceSpaceGapY + 10); theImage = theImage.Add(currSignImage.TextSignImageAtOriginalBlank(markerColor)); currentMarkerValueX += rulerValueGapX; nextXPositionDouble = leftServiceSpaceGapX + ((currentMarkerValueX - xSpaceMin) / (xSpaceMax - xSpaceMin)) * (double)(pictureWidth - leftServiceSpaceGapX - rightServiceSpaceGapX); } #endregion X #endregion Прописываем текстовые маркеры int xValuesCount = pictureWidth - leftServiceSpaceGapX - rightServiceSpaceGapX;// оставляем место на шкалу Y List <Point> rulerVertices = new List <Point>(); rulerVertices.Add(new Point(leftServiceSpaceGapX, pictureHeight - btmServiceSpaceGapY)); rulerVertices.Add(new Point(pictureWidth - rightServiceSpaceGapX, pictureHeight - btmServiceSpaceGapY)); rulerVertices.Add(new Point(pictureWidth - rightServiceSpaceGapX, topServiceSpaceGapY)); rulerVertices.Add(new Point(leftServiceSpaceGapX, topServiceSpaceGapY)); theImage.DrawPolyline(rulerVertices.ToArray(), true, colorGreen, 2); double koeff = (pictureHeight - btmServiceSpaceGapY - topServiceSpaceGapY) / (overallFuncMax - overallFuncMin); koeffY = ((double)pictureHeight - btmServiceSpaceGapY - topServiceSpaceGapY) / (overallFuncMax - overallFuncMin); koeffX = ((double)pictureWidth - leftServiceSpaceGapX - rightServiceSpaceGapX) / (xSpaceMax - xSpaceMin); if (equalScale) { koeff = Math.Min(koeffY, koeffX); koeffY = koeff; koeffX = koeff; } if (drawZeroLines) { int zeroYcoordinate = Convert.ToInt32(pictureHeight - btmServiceSpaceGapY - (0 - overallFuncMin) * koeffY); int zeroXcoordinate = Convert.ToInt32(leftServiceSpaceGapX + (0 - xSpaceMin) * koeffX); List <Point> rulerXVertices = new List <Point>(); rulerXVertices.Add(new Point(leftServiceSpaceGapX, zeroYcoordinate)); rulerXVertices.Add(new Point(pictureWidth - rightServiceSpaceGapX, zeroYcoordinate)); theImage.DrawPolyline(rulerXVertices.ToArray(), false, colorGreen, 2); List <Point> rulerYVertices = new List <Point>(); rulerYVertices.Add(new Point(zeroXcoordinate, topServiceSpaceGapY)); rulerYVertices.Add(new Point(zeroXcoordinate, pictureHeight - btmServiceSpaceGapY)); theImage.DrawPolyline(rulerYVertices.ToArray(), false, colorGreen, 2); } DenseVector dvXSpaceValues = DenseVector.Create(xValuesCount, new Func <int, double>(i => xSpaceMin + ((double)i / ((double)xValuesCount - 1.0d)) * (xSpaceMax - xSpaceMin))); DenseVector parametersList = null; for (int i = 0; i < theRepresentingFunctions.Count; i++) { Func <DenseVector, double, double> theRepresentingFunction = theRepresentingFunctions[i]; DenseVector currentParametersList = parameters[i]; DenseVector dvFuncValues = DenseVector.Create(xValuesCount, new Func <int, double>(j => theRepresentingFunction(currentParametersList, dvXSpaceValues[j]))); double funcMax = dvFuncValues.Max(); double funcMin = dvFuncValues.Min(); overallFuncMax = (funcMax > overallFuncMax) ? (funcMax) : (overallFuncMax); overallFuncMin = (funcMin < overallFuncMin) ? (funcMin) : (overallFuncMin); } for (int i = 0; i < theRepresentingFunctions.Count; i++) { Func <DenseVector, double, double> theRepresentingFunction = theRepresentingFunctions[i]; DenseVector currentParametersList = parameters[i]; //DenseVector dvXSpaceValues = DenseVector.Create(xValuesCount, new Func<int, double>(i => xSpaceMin + ((double)i / ((double)xValuesCount - 1.0d)) * (xSpaceMax - xSpaceMin))); parametersList = null; DenseVector dvFuncValues = DenseVector.Create(xValuesCount, new Func <int, double>(j => theRepresentingFunction(currentParametersList, dvXSpaceValues[j]))); Bgr currentLineColor = lineColors[i]; DenseVector xCoordinates = DenseVector.Create(xValuesCount, new Func <int, double>(j => ((double)leftServiceSpaceGapX + j))); DenseVector yCoordinates = DenseVector.Create(xValuesCount, new Func <int, double>(j => { double pixValue = koeff * (dvFuncValues[j] - overallFuncMin); return(pictureHeight - btmServiceSpaceGapY - pixValue); })); List <Point> funcRepresentationPoints = new List <Point>(); for (int j = 0; j < xValuesCount; j++) { if (double.IsNaN(yCoordinates[j])) { continue; } funcRepresentationPoints.Add(new Point(Convert.ToInt32(xCoordinates[j]), Convert.ToInt32(yCoordinates[j]))); } theImage.DrawPolyline(funcRepresentationPoints.ToArray(), false, currentLineColor, 2); } }