/// <summary> /// Plots this equation explicitly on the graph. This is faster than implicit plotting but plotting explicitly with respect /// to a variable (eg. <c>'y'</c>) requires that variable to occur once and once only in an equation, alone on one side of /// the equation. For example, the equation <c>y=x^2-3x+2</c> explicitly defines the value of y, but <c>y^2+x^2=4</c> does not, /// instead using it generally in the terms of the equation. This method plots <paramref name="explicitVariable"/> on the /// vertical axis of <paramref name="graph"/>. /// </summary> /// <param name="graph">The Graph to plot this IPlottable onto.</param> /// <param name="graphics">The GDI+ drawing surface to use for plotting this IPlottable.</param> /// <param name="graphSize">The size of the Graph on the screen. This is a property of the display rather than the /// graph and is thus not included in the graph's parameters.</param> /// <param name="graphPen">The pen to use for drawing the curve of the equation.</param> /// <param name="resolution">The plotting resolution to use. Using a coarser resolution may make the plotting /// process faster, and is thus more suitable when the display is being resized or moved.</param> /// <param name="explicitVariable">The variable that is explicitly defined.</param> /// <param name="node">The parse tree node representing what <paramref name="explicitVariable"/> is explicitly equal to.</param> private void PlotExplicitVertical(Graph graph, Graphics graphics, Size graphSize, Pen graphPen, char explicitVariable, ParseTreeNode node, PlotResolution resolution) { VariableSet vars = new VariableSet(); int previousX = -1, previousY = -1; // use wider intervals for coarser plot resolutions float interval = 0.1f; if (resolution == PlotResolution.Resize) { interval *= 100f; } if (resolution == PlotResolution.Edit) { interval *= 40f; } // evaluate the equation at every point along the axis and plot accordingly for (float i = 0; i < graphSize.Width; i += interval) { double vertical = graph.Parameters.VerticalPixelScale * -(i - graphSize.Height / 2) + graph.Parameters.CenterVertical; vars[explicitVariable] = vertical; double horizontal = node.Evaluate(vars); int x, y; graph.ToImageSpace(graphSize, horizontal, vertical, out x, out y); if (previousX != -1) { if (x < -100 || x >= graphSize.Width + 100) { x = -1; y = -1; } else { try { graphics.DrawLine(graphPen, previousX, previousY, x, y); } catch (OverflowException) // can happen if the graph line shoots up tending to infinity { x = -1; y = -1; } } } previousX = x; previousY = y; } }