/* * /// <summary> * /// Represents a raster line * /// </summary> * public class Line { * /// <summary> * /// The x-coordinate of the line * /// </summary> * public double x; * /// <summary> * /// Indicates if the line is a big or small raster line * /// </summary> * public bool big = false; * } * /// <summary> * /// Represents all raster lines of a scale * /// </summary> * public class ScaleLines: List<Line> { } * /// <summary> * /// Draws the scale and raster lines specified in lines. * /// </summary> */ /* * public void DrawScaleLines(Graphics g, PlotModel Model, Scale scale, bool draw, PointF[] v, ref Norms norms, , * ScaleLines lines) { * * Norms normsText = new Norms(); * Norm yNorm; * * // init matrices * Matrix id, T0, T, Tprod, Trot, Tinv; * * id = new Matrix(); * T0 = g.Transform.Clone(); * RectangleF Tframe = Bounds; * T = new Matrix(Tframe, v); * norms.T = normsText.T = T; * Tinv = T.Clone(); * Tinv.Invert(); * Tprod = T0.Clone(); * Tprod.Multiply(T); * Trot = new Matrix(); * if (scale.unitAngleRelative) Trot.Rotate(scale.unitAngle - Angle(Diff(v[1], v[0]))); * else Trot.Rotate(scale.unitAngle); * g.Transform = Tprod; * * PointF[] p = new PointF[4]; * double x0 = scale.lower, x1 = scale.upper; * if (x0 > x1) { * double t = x0; x0 = x1; x1 = t; * } * // double d = (x1 - x0)/W; * // double x = Math.Floor(x0/scale.r)*scale.r + scale.r; * double sr = scale.r/5; * float Y, X0 = scale.DeviceCoordinate(0, Bounds); * SizeF size = g.MeasureString("0.5", Model.ScaleFont); * float s, s0 = Math.Max(1, (int)(size.Height + 0.5F)); * Pen pen = new Pen(Model.ScaleColor, Model.ScaleLineWidth); // the pen used for drawing * SolidBrush brush = new SolidBrush(Model.ScaleColor); * SolidBrush background = new SolidBrush(Model.BackgroundColor); * foreach (Line l in lines) { // interate over raster * if (x0 <= l.x && l.x <= x1) { * float X = scale.DeviceCoordinate(l.x, Bounds); * bool isX0 = Math.Round(X0) == Math.Round(X); * if (draw && (!isX0 || !scale.axis)) { // X is not axis * if (scale.grid && l.big) { // draw grid * pen.Color = Color.FromArgb(255, Model.ScaleColor); * g.DrawLine(pen, X, 0, X, Bounds.Height); * pen.Color = Model.ScaleColor; * } * if (scale.raster) { // draw raster * if (l.big) s = s0; * else s = s0/2; * if (scale.rasterOutside) { // draw raster on outside * if (scale.raster) g.DrawLine(pen, X, -s, X, 0); * if (scale.oppositeRaster) g.DrawLine(pen, X, Bounds.Height + s, X, H); * } else { // draw raster on inside * if (scale.raster) g.DrawLine(pen, X, 0, X, s); * if (scale.oppositeRaster) g.DrawLine(pen, X, H - s, X, H); * } * } * } else if (draw && scale.axis) { // draw 0-axis. * g.DrawLine(pen, X, 0, X, H); * } * * if (scale.scale && l.big) { // draw scale text * string label; * if (isX0) label = "0"; * else label = scale.UnitToString(l.x); * * if (scale.scaleOutside != scale.rasterOutside) s = 0.5F*s0; // distance from line to scale * else s = 1.5F*s0; * if (scale.scaleOutside) { // draw scale outside the box * Y = -s; * yNorm = Norm.Max; * } else { // draw scale inside the box * Y = s; * yNorm = Norm.Min; * } * g.Transform = T0; // reset transformation * DrawText(g, label, draw, Model.ScaleFont, brush, background, X, Norm.Average, Y, yNorm, id, T, Tinv, ref p, ref normsText); * g.Transform = Tprod; * } * } * } * * // draw units * g.Transform = T0; * * size = g.MeasureString(scale.unit, Model.UnitsFont); * s0 = size.Height/2; * * if (scale.scaleOutside) { * Y = normsText.min.Y - s0; yNorm = Norm.Max; // draw the units below the scale * } else { * Y = normsText.max.Y + s0; yNorm = Norm.Min; // draw the units above the scale * } * DrawText(g, scale.unit, draw, Model.UnitsFont, brush, background, W/2, Norm.Average, Y, yNorm, Trot, T, Tinv, ref p, ref norms); * norms += normsText; * } */ /// <summary> /// Draws a <see cref="Scale">Scale</see>. The point-array v is an array of 3 points that denote the orientation /// of the scale. The primary scale is drawn from v[0] -> v[1], the opposite scale is drawn from /// v[0] + v[2] -> v[1] + v[2]. /// </summary> /// <param name="g">The <see cref="Graphics"/> object to draw to.</param> /// <param name="v">The orientation of the scale</param> /// <param name="Model">The <see cref="PlotModel"/> of the Plot to draw</param> /// <param name="scale">The scale to draw</param> /// <param name="draw">If false, the scale is not drawn but it's dimensions are added to norms.</param> /// <param name="norms">The <see cref="Norms"/> the extension-points of the scale will be added to.</param> public static void DrawScale(Graphics g, PointF[] v, PlotModel Model, Scale scale, bool draw, ref Norms norms) { //TODO Inverse Scales (where scale.lower > scale.upper) //TODO logscales const int GridAlpha = 64; // the alpha-color value of the grid lines. float X, X0, Y, W, H, s, s0; double x, sr, t, x0, x1; Matrix id, T0, T, Tprod, Trot, Tinv; int n, Width; Pen pen = new Pen(Model.ScaleColor, Model.ScaleLineWidth); // the pen used for drawing SolidBrush brush = new SolidBrush(Model.ScaleColor); SolidBrush background = new SolidBrush(Model.BackgroundColor); string label; RectangleF Tframe; PointF d1, d2, d3; bool isX0; Norm yNorm; PointF[] p = new PointF[4]; SizeF size; Norms normsText = new Norms(); x0 = scale.lower; x1 = scale.upper; if (x0 > x1) // lower bound is greater than upper bound. Exchange bounds. { t = x0; x0 = x1; x1 = t; } d1 = Diff(v[1], v[0]); d2 = Diff(v[2], v[0]); d3 = Diff(v[1], v[2]); if (v[0] == v[1] || v[0] == v[2] || v[1] == v[2]) { return; } W = (float)Math.Sqrt(d1.X * d1.X + d1.Y * d1.Y); H = (float)Math.Sqrt(d2.X * d2.X + d2.Y * d2.Y); W = Math.Max(W, 1); H = Math.Max(H, 1); Width = (int)(W + 1.5); Tframe = new RectangleF(0, 0, W, H); size = g.MeasureString("0.5", Model.ScaleFont); s0 = Math.Max(1, size.Height); // init matrices id = new Matrix(); T0 = g.Transform.Clone(); T = new Matrix(Tframe, v); norms.T = normsText.T = T; Tinv = T.Clone(); Tinv.Invert(); Tprod = T0.Clone(); Tprod.Multiply(T); Trot = new Matrix(); if (scale.unitAngleRelative) { Trot.Rotate(scale.unitAngle - Angle(Diff(v[1], v[0]))); } else { Trot.Rotate(scale.unitAngle); } g.Transform = Tprod; p[0] = new PointF(0, 0); p[1] = new PointF(W, 0); p[2] = new PointF(W, H); p[3] = new PointF(0, H); norms.Add(p); if (draw) // draw the solid lines of the scale and opposite scale { if (scale.line) { g.DrawLine(pen, p[0], p[1]); } if (scale.oppositeLine) { g.DrawLine(pen, p[3], p[2]); } } // add the minimum rectangle to the normsText. (So that the units will be in the right position, even if there is no scale.) if (scale.scaleOutside != scale.rasterOutside) { s = 0.5F * s0; } else { s = 1.5F * s0; } if (scale.scaleOutside) { s = -s; } Y = s; p[0] = new PointF(0, Y); p[1] = new PointF(W, Y); p[2] = new PointF(W, Y); p[3] = new PointF(0, Y); normsText.Add(p); // draw scale if (!scale.logarithmic) { sr = scale.r; x = Math.Floor(x0 / sr) * sr + sr; sr = sr / 5; X0 = scale.DeviceCoordinate(0, (int)(W + 0.5F)); n = -4; // interate over raster while ((sr > 0 && x + sr * n < x0) || (sr < 0 && x + sr * n > x0)) { n++; } while ((sr > 0 && x + sr * n < x1) || (sr < 0 && x + sr * n > x1)) { X = scale.DeviceCoordinate(x + sr * n, (int)(W + 0.5F)); // X = (float)((x + sr*n - x0)/d); isX0 = Math.Round(X0) == Math.Round(X); if (draw && (!isX0 || !scale.axis)) // X is not axis { if (scale.grid && n % 5 == 0) // draw grid { pen.Color = Color.FromArgb(GridAlpha, Model.ScaleColor); g.DrawLine(pen, X, 0, X, H); pen.Color = Model.ScaleColor; } if (scale.raster) // draw raster { if (n % 5 == 0) { s = s0; } else { s = s0 / 2; } if (scale.rasterOutside) // draw raster on outside { if (scale.raster) { g.DrawLine(pen, X, -s, X, 0); } if (scale.oppositeRaster) { g.DrawLine(pen, X, H + s, X, H); } } else // draw raster on inside { if (scale.raster) { g.DrawLine(pen, X, 0, X, s); } if (scale.oppositeRaster) { g.DrawLine(pen, X, H - s, X, H); } } } } else if (scale.axis && draw) // draw 0-axis. { g.DrawLine(pen, X, 0, X, H); } if (scale.scale && (n % 5 == 0)) // draw scale { if (isX0) { label = "0"; } else { label = scale.UnitToString(x + sr * n); } if (scale.scaleOutside != scale.rasterOutside) { s = 0.5F * s0; // distance from line to scale } else { s = 1.5F * s0; } if (scale.scaleOutside) // draw scale outside the box { Y = -s; yNorm = Norm.Max; } else // draw scale inside the box { Y = s; yNorm = Norm.Min; } g.Transform = T0; // reset transformation DrawText(g, label, draw, Model.ScaleFont, brush, null, X, Norm.Average, Y, yNorm, id, T, Tinv, ref p, ref normsText); g.Transform = Tprod; } n++; } } else //scale is logarithmic { double l0 = Math.Log10(Math.Abs(x0)), l1 = Math.Log10(Math.Abs(x1)); double ld = l1 - l0; } // draw units g.Transform = T0; size = g.MeasureString(scale.unit, Model.UnitsFont); s0 = size.Height / 2; if (scale.scaleOutside) { Y = normsText.min.Y - s0; yNorm = Norm.Max; // draw the units below the scale } else { Y = normsText.max.Y + s0; yNorm = Norm.Min; // draw the units above the scale } DrawText(g, scale.unit, draw, Model.UnitsFont, brush, null, W / 2, Norm.Average, Y, yNorm, Trot, T, Tinv, ref p, ref norms); norms += normsText; }