private static Tuple<int[][], int[][]> DrawSetOfCurves(double[][] masX, double[][] masY, int countOfCurves, OutFromIntelMeshing inClass) { int[][] curveCoordY = new int[countOfCurves + 1][]; int[][] curveCoordX = new int[countOfCurves + 1][]; int lenBetweenYLines = (HPlot - 2 * Border) / inClass.NumOfYLines; int lenBetweenXLines = (WPlot - Border - BorderAtRight) / inClass.NumOfXLines; // сохраняем информацию, чтобы выполнять запросы (координата - реальная координата) _masXg = masX; _masYg = masY; for (int n = 1; n <= countOfCurves; n++) { int countOfPoints = (int) masX[n][0]; curveCoordY[n] = new int[countOfPoints + 1]; curveCoordX[n] = new int[countOfPoints + 1]; var x = new int[countOfPoints + 1]; var y = new int[countOfPoints + 1]; // выбираем цвет кривой var pen = countOfPoints >= 3 ? new Pen(SwitchColor(masY[n][1], masY[n][countOfPoints / 2], masY[n][countOfPoints]), 1) : new Pen(SwitchColor(n, n, n), 1); for (int i = 1; i <= countOfPoints; i++) { double fracX = (masX[n][i] - inClass.StartX) / inClass.LenX, fracY = (masY[n][i] - inClass.StartY) / inClass.LenY; if (fracX > 1 || fracX < 0 || fracY > 1 || fracY < 0) continue; x[i] = (int)(Border + fracX * (inClass.NumOfXLines * lenBetweenXLines)); y[i] = (int)(Border + fracY * (inClass.NumOfYLines * lenBetweenYLines)); if (y[i - 1] != 0) DrawLineCurveS2P(x[i], y[i], x[i - 1], y[i - 1], pen); // сохраняем координаты точек, где рисовали curveCoordY[n][i] = y[i]; curveCoordX[n][i] = x[i]; } } return Tuple.Create(curveCoordX, curveCoordY); }
static OutFromIntelMeshing IntelligentMeshing(double minX, double maxX, double minY, double maxY) { double bestXRating = 0, bestStepX = 0, bestStartX = 0, bestYRating = 0, bestStepY = 0, bestStartY = 0; int bestNumOfXLines = 0, bestNumOfYLines = 0; minX = TruncOfDouble(minX); maxX = TruncOfDouble(maxX); minY = TruncOfDouble(minY); maxY = TruncOfDouble(maxY); for (int n = 5; n <= 14; n++) { double stepX = (maxX - minX) / n; // ориентировочный дробный шаг stepX = GetGoodStep(stepX); // теперь шаги более менее целые с функцией getStep double sttX = stepX * Math.Floor(minX / stepX); // новое начальное значение if (sttX + n * stepX >= maxX) { double curRating = 1; // рейтинговая система оценки "хорошего" подбора сетки графика curRating += 1000 * (1 - (Math.Abs(sttX + n * stepX - maxX) / (n * stepX) )); curRating += 1000 * (1 - (Math.Abs(minX - sttX) / (n * stepX) )); curRating += 5.5 - Math.Abs(n - 10); curRating += 2 * GetCeilMark(stepX); // насколько хорош шаг if (curRating > bestXRating) { bestXRating = curRating; bestStartX = sttX; bestStepX = stepX; bestNumOfXLines = n; } } } for (int n = 5; n <= 14; n++) { double stepY = (maxY - minY) / n; // ориентирвочный дробный шаг stepY = GetGoodStep(stepY); // теперь шаги более менее целые с функцией getStep double sttY = stepY * Math.Floor(minY / stepY); // новое начальное значение if (sttY + n * stepY >= maxY) { double curRating = 1; // рейтинговая система оценки "хорошего" подбора сетки графика curRating += 1000 * (1 - (Math.Abs(sttY + n * stepY - maxY) / (n * stepY)) ); curRating += 1000 * (1 - (Math.Abs(minY - sttY) / (n * stepY)) ); curRating += 5.5 - Math.Abs(n - 10); curRating += 2 * GetCeilMark(stepY); // насколько хорош шаг if (curRating > bestYRating) { bestYRating = curRating; bestStartY = sttY; bestStepY = stepY; bestNumOfYLines = n; } } } // сохраняем полученные результаты в класс и отдаем OutFromIntelMeshing outClass = new OutFromIntelMeshing(); if (bestNumOfXLines != 0) { outClass.StartX = bestStartX; outClass.LenX = bestStepX * bestNumOfXLines; outClass.NumOfXLines = bestNumOfXLines; outClass.StepX = bestStepX; // сохраняем глобальные переменные для обработки запросов координат _lenXReal = outClass.LenX; _startX = outClass.StartX; } if (bestNumOfYLines != 0) { outClass.StartY = bestStartY; outClass.LenY = bestStepY * bestNumOfYLines; outClass.NumOfYLines = bestNumOfYLines; outClass.StepY = bestStepY; // сохраняем глобальные переменные для обработки запросов координат _lenYReal = outClass.LenY; _startY = outClass.StartY; } return outClass; }
private static void DrawMesh(OutFromIntelMeshing inClass) { // подгонка: растягиваем либо сужаем в зависимости от размера окна int lenBetweenYLines = (HPlot - 2 * Border) / inClass.NumOfYLines; int lenBetweenXLines = (WPlot - Border - BorderAtRight) / inClass.NumOfXLines; for (int i = 0; i <= inClass.NumOfXLines; i++) // вертикальные линии { PrintTextPlot(Border + i * lenBetweenXLines - 10, Border - 10, 10, DoubleToStr(inClass.StartX + i * inClass.StepX)); if (i > 0 && i < inClass.NumOfXLines) DrawLineMesh(Border + i * lenBetweenXLines, Border, Border + i * lenBetweenXLines, Border + inClass.NumOfYLines * lenBetweenYLines); else DrawLinePlot(Border + i * lenBetweenXLines, Border, Border + i * lenBetweenXLines, Border + inClass.NumOfYLines * lenBetweenYLines); } for (int i = 0; i <= inClass.NumOfYLines; i++) // горионтальные линии { PrintTextPlot(Border - 45, Border + i * lenBetweenYLines + 10, 10, DoubleToStr(inClass.StartY + i * inClass.StepY)); if (i > 0 && i < inClass.NumOfYLines) DrawLineMesh(Border, Border + i * lenBetweenYLines, Border + inClass.NumOfXLines * lenBetweenXLines, Border + i * lenBetweenYLines); else DrawLinePlot(Border, Border + i * lenBetweenYLines, Border + inClass.NumOfXLines * lenBetweenXLines, Border + i * lenBetweenYLines); } }