public override void Graph(System.Drawing.Image dest, GraphingArgs ga, double xMin, double xMax, double yMin, double yMax) { if (pens != null) { ga.CurvePen = pens[0]; } copyGrapherSignature(this, grapherArray[0]); grapherArray[0].Graph(dest, ga, xMin, xMax, yMin, yMax); // Отключим рисование сетки, насечек и номеров GraphingArgs newArgs = (GraphingArgs)ga.Clone(); newArgs.GridPen = null; newArgs.CoordFont = null; newArgs.CoordPen = null; newArgs.BackgroundBrush = null; for (int i = 1; i < grapherArray.Length; i++) { if (pens != null) { newArgs.CurvePen = pens[i]; } copyGrapherSignature(this, grapherArray[i]); grapherArray[i].Graph(dest, newArgs, xMin, xMax, yMin, yMax); } }
private void GraphSkeleton(System.Drawing.Image destinationImage, GraphingArgs graphingArgs, double xMin, double xMax, double yMin, double yMax, IList<Point<double>> pointsArray) { ArrayGrapher tmp = new ArrayGrapher(pointsArray); copyGrapherSignature(this, tmp); tmp.Graph(destinationImage, graphingArgs, xMin, xMax, yMin, yMax); }
public override void Graph(Image dest, GraphingArgs ga, double xMin, double xMax) { double yMin, yMax; findYminYmax(xMin, xMax, out yMin, out yMax); // ищем макс и мин по y для заданного диапазона this.Graph(dest, ga, xMin, xMax, yMin, yMax); }
private void GraphSkeleton(System.Drawing.Image destinationImage, GraphingArgs graphingArgs, double xMin, double xMax, double yMin, double yMax, IList <Point <double> > pointsArray) { ArrayGrapher tmp = new ArrayGrapher(pointsArray); copyGrapherSignature(this, tmp); tmp.Graph(destinationImage, graphingArgs, xMin, xMax, yMin, yMax); }
public override void Graph(System.Drawing.Image destinationImage, GraphingArgs graphingArgs, double xMin, double xMax, double yMin, double yMax) { if (xMin >= xMax || yMin >= yMax) throw new GrapherGraphException("Диапазоны должны задаваться от меньшего числа к большему."); double dummy; IList<Point<double>> pointsArray = GetPointsArraySkeleton(dotCount, xMin, xMax, out dummy, out dummy); GraphSkeleton(destinationImage, graphingArgs, xMin, xMax, yMin, yMax, pointsArray); }
public override void Graph(System.Drawing.Image destinationImage, GraphingArgs graphingArgs, double xMin, double xMax, double yMin, double yMax) { if (xMin >= xMax || yMin >= yMax) { throw new GrapherGraphException("Диапазоны должны задаваться от меньшего числа к большему."); } double dummy; IList <Point <double> > pointsArray = GetPointsArraySkeleton(dotCount, xMin, xMax, out dummy, out dummy); GraphSkeleton(destinationImage, graphingArgs, xMin, xMax, yMin, yMax, pointsArray); }
public override void Graph(Image dest, GraphingArgs ga, double xMin, double xMax, double yMin, double yMax) { if (!isNormalPoint(xMin, xMax) || !isNormalPoint(yMin, yMax)) { throw new GrapherActionImpossibleException("Invalid graphing bounds: containing NaNs or infinities."); } // создаем массив точек для рисования MakeGraphingArray(xMin, xMax, yMin, yMax); // собственно рисуем все GraphMethodSkeleton(dest, ga, xMin, xMax, yMin, yMax); }
// --------------------------------- // ------- MAIN GRAPH METHOD ------- // --------------------------------- private void buttonGraph_Click(object sender, EventArgs e) { this.somethingIsDrawn = false; // reset the bool value to false. Pen CurvePen = new Pen(new SolidBrush(multiGrapherPens1.getCurveColor()), (int)numericUpDownCW.Value); Pen CoordPen = new Pen(new SolidBrush(multiGrapherPens1.getAxisColor()), (int)numericUpDownAW.Value); Brush BackBrush = new SolidBrush(multiGrapherPens1.getBackgroundColor()); if (checkBoxNotWindowed.Checked) drawnImage = new Bitmap((int)numericUpDownWidth.Value, (int)numericUpDownHeight.Value); else drawnImage = new Bitmap(pictureBoxWindow.Width, pictureBoxWindow.Height); // --------- Работа с масштабированием #region CheckingTextboxValidating // если юзер перемещается мышкой, то не надо парсить текстбоксы. // это занимает время. if (!(e is EventArgs_NoCheck)) { if (!double.TryParse(textBoxFromX.Text, out xMin)) { MessageBox.Show(this, "Невозможно определить значение нижней границы масштабирования. Проверьте правильность ввода.", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Error); textBoxFromX.Clear(); textBoxFromX.Focus(); return; } if (!double.TryParse(textBoxToX.Text, out xMax)) { MessageBox.Show(this, "Невозможно определить значение верхней границы масштабирования. Проверьте правильность ввода.", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Error); textBoxToX.Clear(); textBoxToX.Focus(); return; } if (!double.TryParse(textBoxFromY.Text, out yMin)) { MessageBox.Show(this, "Невозможно определить значение нижней границы масштабирования. Проверьте правильность ввода.", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Error); textBoxFromY.Clear(); textBoxFromY.Focus(); return; } if (!double.TryParse(textBoxToY.Text, out yMax)) { MessageBox.Show(this, "Невозможно определить значение верхней границы масштабирования. Проверьте правильность ввода.", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Error); textBoxToY.Clear(); textBoxToY.Focus(); return; } } // --------- Назначаем шаг if (yMax != yMin && !double.IsNaN(yMax) && !double.IsInfinity(yMin)) { G.Axis1CoordinateStep = (xMax - xMin) / (int)numericUpDownParts.Value; G.Axis2CoordinateStep = (yMax - yMin) / (int)numericUpDownParts.Value; } #endregion string formatter; // --------- Точность на оси X formatter = "{0:G"; formatter+=numericUpDownEX.Value.ToString()+"}"; G.Axis1NumbersFormatter = formatter; // --------- Точность на оси Y formatter = "{0:G"; formatter += numericUpDownEX2.Value.ToString() + "}"; G.Axis2NumbersFormatter = formatter; // ------------------------------------- try { GraphingArgs graphingArgs = new GraphingArgs( (int)numericUpDownShift.Value, BackBrush, CoordPen, CoordFont, new Pen(Color.FromArgb(CoordPen.Color.A/4, CoordPen.Color)), CurvePen, LT); // ---- if multigrapher, set pens // ---- and the width! if (G is MultiGrapher) { Pen[] arr = multiGrapherPens1.getCurveColors().pensFromColors(); for (int i = 0; i < arr.Length; i++) arr[i].Width = (int)numericUpDownCW.Value; (G as MultiGrapher).setPens(arr); } // ---- do it. G.Graph(drawnImage, graphingArgs, xMin, xMax, yMin, yMax); // ---- re-initialize the transformer ctf = new CoordinateTransformer(xMin, xMax, yMin, yMax, (x => x), drawnImage.Size, (int)numericUpDownShift.Value); // ------------------------------------ if (drawnImage.Width <= pictureBoxWindow.Width && drawnImage.Height <= pictureBoxWindow.Height) pictureBoxWindow.Image = drawnImage; else ShowImageInPictureBox(); } catch (GrapherException ex) { MessageBox.Show(this, "Не удалось построить график: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } CurvePen.Dispose(); CoordPen.Dispose(); this.somethingIsDrawn = true; // что-то нарисовали. }
// --------------------------------- // ------- MAIN GRAPH METHOD ------- // --------------------------------- private void buttonGraph_Click(object sender, EventArgs e) { this.somethingIsDrawn = false; // reset the bool value to false. Pen CurvePen = new Pen(new SolidBrush(multiGrapherPens1.getCurveColor()), (int)numericUpDownCW.Value); Pen CoordPen = new Pen(new SolidBrush(multiGrapherPens1.getAxisColor()), (int)numericUpDownAW.Value); Brush BackBrush = new SolidBrush(multiGrapherPens1.getBackgroundColor()); if (checkBoxNotWindowed.Checked) { drawnImage = new Bitmap((int)numericUpDownWidth.Value, (int)numericUpDownHeight.Value); } else { drawnImage = new Bitmap(pictureBoxWindow.Width, pictureBoxWindow.Height); } // --------- Работа с масштабированием #region CheckingTextboxValidating // если юзер перемещается мышкой, то не надо парсить текстбоксы. // это занимает время. if (!(e is EventArgs_NoCheck)) { if (!double.TryParse(textBoxFromX.Text, out xMin)) { MessageBox.Show(this, "Невозможно определить значение нижней границы масштабирования. Проверьте правильность ввода.", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Error); textBoxFromX.Clear(); textBoxFromX.Focus(); return; } if (!double.TryParse(textBoxToX.Text, out xMax)) { MessageBox.Show(this, "Невозможно определить значение верхней границы масштабирования. Проверьте правильность ввода.", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Error); textBoxToX.Clear(); textBoxToX.Focus(); return; } if (!double.TryParse(textBoxFromY.Text, out yMin)) { MessageBox.Show(this, "Невозможно определить значение нижней границы масштабирования. Проверьте правильность ввода.", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Error); textBoxFromY.Clear(); textBoxFromY.Focus(); return; } if (!double.TryParse(textBoxToY.Text, out yMax)) { MessageBox.Show(this, "Невозможно определить значение верхней границы масштабирования. Проверьте правильность ввода.", "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Error); textBoxToY.Clear(); textBoxToY.Focus(); return; } } // --------- Назначаем шаг if (yMax != yMin && !double.IsNaN(yMax) && !double.IsInfinity(yMin)) { G.Axis1CoordinateStep = (xMax - xMin) / (int)numericUpDownParts.Value; G.Axis2CoordinateStep = (yMax - yMin) / (int)numericUpDownParts.Value; } #endregion string formatter; // --------- Точность на оси X formatter = "{0:G"; formatter += numericUpDownEX.Value.ToString() + "}"; G.Axis1NumbersFormatter = formatter; // --------- Точность на оси Y formatter = "{0:G"; formatter += numericUpDownEX2.Value.ToString() + "}"; G.Axis2NumbersFormatter = formatter; // ------------------------------------- try { GraphingArgs graphingArgs = new GraphingArgs( (int)numericUpDownShift.Value, BackBrush, CoordPen, CoordFont, new Pen(Color.FromArgb(CoordPen.Color.A / 4, CoordPen.Color)), CurvePen, LT); // ---- if multigrapher, set pens // ---- and the width! if (G is MultiGrapher) { Pen[] arr = multiGrapherPens1.getCurveColors().pensFromColors(); for (int i = 0; i < arr.Length; i++) { arr[i].Width = (int)numericUpDownCW.Value; } (G as MultiGrapher).setPens(arr); } // ---- do it. G.Graph(drawnImage, graphingArgs, xMin, xMax, yMin, yMax); // ---- re-initialize the transformer ctf = new CoordinateTransformer(xMin, xMax, yMin, yMax, (x => x), drawnImage.Size, (int)numericUpDownShift.Value); // ------------------------------------ if (drawnImage.Width <= pictureBoxWindow.Width && drawnImage.Height <= pictureBoxWindow.Height) { pictureBoxWindow.Image = drawnImage; } else { ShowImageInPictureBox(); } } catch (GrapherException ex) { MessageBox.Show(this, "Не удалось построить график: " + ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } CurvePen.Dispose(); CoordPen.Dispose(); this.somethingIsDrawn = true; // что-то нарисовали. }
private void GraphMethodSkeleton(Image dest, GraphingArgs graphingArgs, double xMin, double xMax, double yMin, double yMax) { if (dest.Width <= 0 || dest.Height <= 0) throw new GrapherActionImpossibleException("Размеры картинки являются отрицательными!"); if (dest.Height < graphingArgs.IndentFromBounds * 2) graphingArgs.IndentFromBounds = dest.Height / 2; if (dest.Width <= graphingArgs.IndentFromBounds * 2) graphingArgs.IndentFromBounds = dest.Width / 2; if (GraphingArray == null) throw new GrapherActionImpossibleException("Массив точек является пустой ссылкой или массивом длины меньше 2! Если Вы используете ExcelGrapher, сначала вызовите метод GetPoints() из соответствующего экземпляра класса."); // ------------ Получение объекта Graphics и настройки Graphics G = Graphics.FromImage(dest); G.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; G.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; // ------------ заливка фона if(graphingArgs.BackgroundBrush != null) G.FillRectangle(graphingArgs.BackgroundBrush, new Rectangle(0, 0, dest.Width, dest.Height)); // ------------ Временные переменные для удобства int Width = dest.Width; int Height = dest.Height; int Shift = graphingArgs.IndentFromBounds; // ------------ Вырожденный случай, // ------------ надо предусмотреть. if (xMin == xMax) { xMin = xMin - 10; xMax = xMax + 10; } if (yMax == yMin) { yMin = yMin - 10; yMax = yMax + 10; } // ------------ Изменение объекта CoordinateTransformer ctf = new CoordinateTransformer(xMin, xMax, yMin, yMax, (x => x), new Size(Width, Height), Shift); // ----------- НАЗНАЧЕНИЕ ШАГА НАСЕЧЕК ------------ if (Step1 == 0) Step1 = (xMax - xMin) / 10; // шаги по умолчанию if (Step2 == 0) Step2 = (yMax - yMin) / 10; // шаги по умолчанию // ------------------------------------------------ // ----------- Назначение координат точек в зависимости от экстремальных значений // ----------- аргумента и функции PointF Zero = (PointF)ctf.CoordinateSystemCenter, Left = (PointF)ctf.CoordinateSystemLeft, Right = (PointF)ctf.CoordinateSystemRight, Up = (PointF)ctf.CoordinateSystemUp, Down = (PointF)ctf.CoordinateSystemDown; double kx = 1 / ctf.TransformerAxisX.ScaleFactor; double ky = 1 / ctf.TransformerAxisY.ScaleFactor; double alpha, beta; alpha = xMax <= 0 ? xMax : (xMin >= 0 ? xMin : 0); beta = yMax <= 0 ? yMax : (yMin >= 0 ? yMin : 0); // ------------ Рисуем начало координат // ------------ (в данный момент не рисуется) // G.DrawString("N(" + String.Format(formatter1, alpha) + ";" + String.Format(formatter2, beta) + ")", graphingArgs.CoordFont, Brushes.Black, new PointF(Zero.X - 10, Zero.Y)); // ------------ Рисуем сетку и оси if (graphingArgs.GridPen != null) DrawCoordGrid(G, graphingArgs.GridPen, Zero, Left, Right, Up, Down, kx, ky); if (graphingArgs.CoordPen != null) DrawCoordinates(G, graphingArgs.CoordPen, Zero, Left, Right, Up, Down, kx, ky); // ------------ Рисуем графики if (graphingArgs.CurvePen != null) { foreach (List<PointF> diapPoints in GraphingArray) { // xxx Вычисляем окончательные координаты точек на картинке. for (int i = 0; i < diapPoints.Count; i++) diapPoints[i] = (PointF)ctf.transformFunctionToPixel(diapPoints[i].X, diapPoints[i].Y); // xxx Если единственная точка в диапазоне, рисуем ее в виде эллипса. if (diapPoints.Count == 1) G.FillEllipse(new SolidBrush(graphingArgs.CurvePen.Color), diapPoints[0].X, diapPoints[0].Y, graphingArgs.CurvePen.Width + 2, graphingArgs.CurvePen.Width + 2); // xxx Если несколько точек, проводим кривую / ломаную. else switch (graphingArgs.CurveType) { case LineType.Polygon: G.DrawPolygon(graphingArgs.CurvePen, diapPoints.ToArray()); break; case LineType.Line: G.DrawLines(graphingArgs.CurvePen, diapPoints.ToArray()); break; case LineType.CardinalCurve: G.DrawCurve(graphingArgs.CurvePen, diapPoints.ToArray()); break; } } } // ------ Рисование цифр на насечках // ------ (в последнюю очередь, чтобы цифры располагались НАД кривыми) if (graphingArgs.CoordFont != null) DrawCoordNumbers(G, graphingArgs.CoordFont, Zero, Left, Right, Up, Down, kx, ky); // ------ Уничтожение объекта Graphics G.Dispose(); }
public override void Graph(Image dest, GraphingArgs ga, double xMin, double xMax, double yMin, double yMax) { if (!isNormalPoint(xMin, xMax) || !isNormalPoint(yMin, yMax)) throw new GrapherActionImpossibleException("Invalid graphing bounds: containing NaNs or infinities."); // создаем массив точек для рисования MakeGraphingArray(xMin, xMax, yMin, yMax); // собственно рисуем все GraphMethodSkeleton(dest, ga, xMin, xMax, yMin, yMax); }
// метод рисует график на основе массива точек. // хочется сразу сказать, что те xMin, xMax, yMin, yMax, // которые здесь фигурируют как локальные переменные - не имеют // ничего общего с нашими родными x...y... вы поняли. #region GraphMethods public override void Graph(Image dest, GraphingArgs ga) { this.Graph(dest, ga, xMin, xMax, yMin, yMax); }
public virtual void Graph(Image dest, GraphingArgs ga, double xMin, double xMax, double yMin, double yMax) { throw ex; }
public virtual void Graph(Image dest, GraphingArgs ga) { throw ex; }
private void GraphMethodSkeleton(Image dest, GraphingArgs graphingArgs, double xMin, double xMax, double yMin, double yMax) { if (dest.Width <= 0 || dest.Height <= 0) { throw new GrapherActionImpossibleException("Размеры картинки являются отрицательными!"); } if (dest.Height < graphingArgs.IndentFromBounds * 2) { graphingArgs.IndentFromBounds = dest.Height / 2; } if (dest.Width <= graphingArgs.IndentFromBounds * 2) { graphingArgs.IndentFromBounds = dest.Width / 2; } if (GraphingArray == null) { throw new GrapherActionImpossibleException("Массив точек является пустой ссылкой или массивом длины меньше 2! Если Вы используете ExcelGrapher, сначала вызовите метод GetPoints() из соответствующего экземпляра класса."); } // ------------ Получение объекта Graphics и настройки Graphics G = Graphics.FromImage(dest); G.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; G.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; // ------------ заливка фона if (graphingArgs.BackgroundBrush != null) { G.FillRectangle(graphingArgs.BackgroundBrush, new Rectangle(0, 0, dest.Width, dest.Height)); } // ------------ Временные переменные для удобства int Width = dest.Width; int Height = dest.Height; int Shift = graphingArgs.IndentFromBounds; // ------------ Вырожденный случай, // ------------ надо предусмотреть. if (xMin == xMax) { xMin = xMin - 10; xMax = xMax + 10; } if (yMax == yMin) { yMin = yMin - 10; yMax = yMax + 10; } // ------------ Изменение объекта CoordinateTransformer ctf = new CoordinateTransformer(xMin, xMax, yMin, yMax, (x => x), new Size(Width, Height), Shift); // ----------- НАЗНАЧЕНИЕ ШАГА НАСЕЧЕК ------------ if (Step1 == 0) { Step1 = (xMax - xMin) / 10; // шаги по умолчанию } if (Step2 == 0) { Step2 = (yMax - yMin) / 10; // шаги по умолчанию } // ------------------------------------------------ // ----------- Назначение координат точек в зависимости от экстремальных значений // ----------- аргумента и функции PointF Zero = (PointF)ctf.CoordinateSystemCenter, Left = (PointF)ctf.CoordinateSystemLeft, Right = (PointF)ctf.CoordinateSystemRight, Up = (PointF)ctf.CoordinateSystemUp, Down = (PointF)ctf.CoordinateSystemDown; double kx = 1 / ctf.TransformerAxisX.ScaleFactor; double ky = 1 / ctf.TransformerAxisY.ScaleFactor; double alpha, beta; alpha = xMax <= 0 ? xMax : (xMin >= 0 ? xMin : 0); beta = yMax <= 0 ? yMax : (yMin >= 0 ? yMin : 0); // ------------ Рисуем начало координат // ------------ (в данный момент не рисуется) // G.DrawString("N(" + String.Format(formatter1, alpha) + ";" + String.Format(formatter2, beta) + ")", graphingArgs.CoordFont, Brushes.Black, new PointF(Zero.X - 10, Zero.Y)); // ------------ Рисуем сетку и оси if (graphingArgs.GridPen != null) { DrawCoordGrid(G, graphingArgs.GridPen, Zero, Left, Right, Up, Down, kx, ky); } if (graphingArgs.CoordPen != null) { DrawCoordinates(G, graphingArgs.CoordPen, Zero, Left, Right, Up, Down, kx, ky); } // ------------ Рисуем графики if (graphingArgs.CurvePen != null) { foreach (List <PointF> diapPoints in GraphingArray) { // xxx Вычисляем окончательные координаты точек на картинке. for (int i = 0; i < diapPoints.Count; i++) { diapPoints[i] = (PointF)ctf.transformFunctionToPixel(diapPoints[i].X, diapPoints[i].Y); } // xxx Если единственная точка в диапазоне, рисуем ее в виде эллипса. if (diapPoints.Count == 1) { G.FillEllipse(new SolidBrush(graphingArgs.CurvePen.Color), diapPoints[0].X, diapPoints[0].Y, graphingArgs.CurvePen.Width + 2, graphingArgs.CurvePen.Width + 2); } // xxx Если несколько точек, проводим кривую / ломаную. else { switch (graphingArgs.CurveType) { case LineType.Polygon: G.DrawPolygon(graphingArgs.CurvePen, diapPoints.ToArray()); break; case LineType.Line: G.DrawLines(graphingArgs.CurvePen, diapPoints.ToArray()); break; case LineType.CardinalCurve: G.DrawCurve(graphingArgs.CurvePen, diapPoints.ToArray()); break; } } } } // ------ Рисование цифр на насечках // ------ (в последнюю очередь, чтобы цифры располагались НАД кривыми) if (graphingArgs.CoordFont != null) { DrawCoordNumbers(G, graphingArgs.CoordFont, Zero, Left, Right, Up, Down, kx, ky); } // ------ Уничтожение объекта Graphics G.Dispose(); }
public override void Graph(System.Drawing.Image dest, GraphingArgs ga, double xMin, double xMax, double yMin, double yMax) { if (pens != null) ga.CurvePen = pens[0]; copyGrapherSignature(this, grapherArray[0]); grapherArray[0].Graph(dest, ga, xMin, xMax, yMin, yMax); // Отключим рисование сетки, насечек и номеров GraphingArgs newArgs = (GraphingArgs)ga.Clone(); newArgs.GridPen = null; newArgs.CoordFont = null; newArgs.CoordPen = null; newArgs.BackgroundBrush = null; for (int i = 1; i < grapherArray.Length; i++) { if (pens != null) newArgs.CurvePen = pens[i]; copyGrapherSignature(this, grapherArray[i]); grapherArray[i].Graph(dest, newArgs, xMin, xMax, yMin, yMax); } }