/* adjust scale of a plot */ void _calcPlotScale(ScopePlot plot) { if (LockScale) { return; } int ipa = plot.StartIndex(BoundingBox.Width); var maxV = plot.MaxValues; var minV = plot.MinValues; double max = 0; double gridMax = mScale; for (int i = 0; i != BoundingBox.Width; i++) { int ip = (i + ipa) & (mScopePointCount - 1); if (max < maxV[ip]) { max = maxV[ip]; } if (minV[ip] < -max) { max = -minV[ip]; } } /* scale fixed at maximum? */ if (mMaxScale) { gridMax = Math.Max(max, gridMax); } else { /* adjust in powers of two */ while (gridMax < max) { gridMax *= 2; } } mScale = gridMax; }
void _drawPlot(CustomGraphics g, ScopePlot plot, bool selected) { if (plot.Elm == null) { return; } int i; int multptr = 0; int x = 0; int maxy = (BoundingBox.Height - 1) / 2; int y = maxy; var color = (mSomethingSelected) ? Color.FromArgb(0xA0, 0xA0, 0xA0) : plot.Color; if (selected || (CirSim.Sim.ScopeSelected == -1 && plot.Elm.IsMouseElm)) { color = CustomGraphics.SelectColor; } else if (ControlPanel.ChkPrintable.Checked) { color = CustomGraphics.GrayColor; } var ipa = plot.StartIndex(BoundingBox.Width); var maxV = plot.MaxValues; var minV = plot.MinValues; var gridMax = mScale; /* if we don't have overlapping scopes of different units, we can move zero around. * Put it at the bottom if the scope is never negative. */ double mx = gridMax; double mn = 0; if (mMaxScale) { /* scale is maxed out, so fix boundaries of scope at maximum and minimum. */ mx = mMaxValue; mn = mMinValue; } else if (mShowNegative || mMinValue < (mx + mn) * .5 - (mx - mn) * .55) { mn = -gridMax; mShowNegative = true; } var gridMid = (mx + mn) * .5; gridMax = (mx - mn) * .55; /* leave space at top and bottom */ double gridMult = maxy / gridMax; if (selected) { mMainGridMult = gridMult; mMainGridMid = gridMid; } int minRangeLo = -10 - (int)(gridMid * gridMult); int minRangeHi = 10 - (int)(gridMid * gridMult); mGridStepY = 1e-8; while (mGridStepY < 20 * gridMax / maxy) { mGridStepY *= MULTA[(multptr++) % 3]; } /* Horizontal gridlines */ int ll; var minorDiv = Color.FromArgb(0x30, 0x30, 0x30); var majorDiv = Color.FromArgb(0xA0, 0xA0, 0xA0); if (ControlPanel.ChkPrintable.Checked) { minorDiv = Color.FromArgb(0xD0, 0xD0, 0xD0); majorDiv = Color.FromArgb(0x80, 0x80, 0x80); } /* Vertical (T) gridlines */ double ts = ControlPanel.TimeStep * Speed; mGridStepX = CalcGridStepX(); if (mDrawGridLines) { /* horizontal gridlines */ /* don't show gridlines if lines are too close together (except for center line) */ bool showGridLines = (mGridStepY != 0); for (ll = -100; ll <= 100; ll++) { if (ll != 0 && !showGridLines) { continue; } int yl = maxy - (int)((ll * mGridStepY - gridMid) * gridMult); if (yl < 0 || yl >= BoundingBox.Height - 1) { continue; } g.LineColor = ll == 0 ? majorDiv : minorDiv; g.DrawLine(0, yl, BoundingBox.Width - 1, yl); } /* vertical gridlines */ double tstart = CirSim.Sim.Time - ControlPanel.TimeStep * Speed * BoundingBox.Width; double tx = CirSim.Sim.Time - (CirSim.Sim.Time % mGridStepX); for (ll = 0; ; ll++) { double tl = tx - mGridStepX * ll; int gx = (int)((tl - tstart) / ts); if (gx < 0) { break; } if (gx >= BoundingBox.Width) { continue; } if (tl < 0) { continue; } if (((tl + mGridStepX / 4) % (mGridStepX * 10)) < mGridStepX) { g.LineColor = majorDiv; } else { g.LineColor = minorDiv; } g.DrawLine(gx, 0, gx, BoundingBox.Height - 1); } } /* only need gridlines drawn once */ mDrawGridLines = false; g.LineColor = color; int ox = -1; int oy = -1; for (i = 0; i != BoundingBox.Width; i++) { int nx = x + i; int ip = (i + ipa) & (mScopePointCount - 1); int minvy = (int)(gridMult * (minV[ip] - gridMid)); int maxvy = (int)(gridMult * (maxV[ip] - gridMid)); if (minvy <= maxy) { if (minvy < minRangeLo || maxvy > minRangeHi) { /* we got a value outside min range, so we don't need to rescale later */ mReduceRange = false; minRangeLo = -1000; minRangeHi = 1000; /* avoid triggering this test again */ } if (ox != -1) { if (minvy == oy && maxvy == oy) { continue; } g.DrawLine(ox, y - oy, nx, y - oy); ox = oy = -1; } if (minvy == maxvy) { ox = nx; oy = minvy; continue; } g.DrawLine(nx, y - minvy, nx, y - maxvy); } } /* for (i=0...) */ if (ox != -1) { g.DrawLine(ox, y - oy, x + i, y - oy); /* Horizontal */ } }