/// <inheritdocs/> protected override void OnPaintOffScreen(PaintEventArgs e) { PolarGraphics f = CreatePolarGraphics(e.Graphics); // What bearing are we drawing? #if PocketPC Azimuth BearingToRender = _Bearing; #else Azimuth bearingToRender = new Azimuth(_valueInterpolator[_interpolationIndex]); #endif // Cache drawing options in order to prevent race conditions during // drawing! double minorInterval = _minorTickInterval.DecimalDegrees; double majorInterval = _majorTickInterval.DecimalDegrees; double directionInterval = _directionLabelInterval.DecimalDegrees; double angleInterval = _angleLabelInterval.DecimalDegrees; // Draw tick marks if (minorInterval > 0) { for (double angle = 0; angle < 360; angle += minorInterval) { // And draw a line f.DrawLine(_minorTickPen, new PolarCoordinate(98, angle), new PolarCoordinate(100, angle)); } } // Draw tick marks if (majorInterval > 0) { for (double angle = 0; angle < 360; angle += majorInterval) { // And draw a line f.DrawLine(_majorTickPen, new PolarCoordinate(95, angle), new PolarCoordinate(100, angle)); } } if (directionInterval > 0) { for (double angle = 0; angle < 360; angle += directionInterval) { // And draw a line f.DrawLine(_directionTickPen, new PolarCoordinate(92, angle), new PolarCoordinate(100, angle)); } } if (angleInterval > 0) { for (double angle = 0; angle < 360; angle += angleInterval) { // Get the coordinate of the line's start PolarCoordinate start = new PolarCoordinate(60, angle, Azimuth.North, PolarCoordinateOrientation.Clockwise); #if PocketPC f.DrawCenteredString(((Angle)angle).ToString(_AngleLabelFormat, CultureInfo.CurrentCulture), _AngleLabelFont, _AngleLabelBrush, start); #else f.DrawRotatedString(((Angle)angle).ToString(_angleLabelFormat, CultureInfo.CurrentCulture), _angleLabelFont, _angleLabelBrush, start); #endif } } if (directionInterval > 0) { for (double angle = 0; angle < 360; angle += directionInterval) { // Get the coordinate of the line's start PolarCoordinate start = new PolarCoordinate(80, angle, Azimuth.North, PolarCoordinateOrientation.Clockwise); #if PocketPC f.DrawCenteredString(((Azimuth)angle).ToString("c", CultureInfo.CurrentCulture), _DirectionLabelFont, _DirectionLabelBrush, start); #else f.DrawRotatedString(((Azimuth)angle).ToString("c", CultureInfo.CurrentCulture), _directionLabelFont, _directionLabelBrush, start); #endif } } // Draw an ellipse at the center f.DrawEllipse(_centerPen, PolarCoordinate.Empty, 10); // Now draw the needle shadow PolarCoordinate[] needleNorth = _needlePointsNorth.Clone() as PolarCoordinate[]; PolarCoordinate[] needleSouth = _needlePointsSouth.Clone() as PolarCoordinate[]; // Adjust the needle to the current bearing if (needleNorth != null) { for (int index = 0; index < needleNorth.Length; index++) { needleNorth[index] = needleNorth[index].Rotate(bearingToRender.DecimalDegrees); if (needleSouth != null) { needleSouth[index] = needleSouth[index].Rotate(bearingToRender.DecimalDegrees); } } } #if !PocketPC // Now draw a shadow f.Graphics.TranslateTransform(_pNeedleShadowSize.Width, _pNeedleShadowSize.Height, MatrixOrder.Append); f.FillPolygon(_pNeedleShadowBrush, needleNorth); f.FillPolygon(_pNeedleShadowBrush, needleSouth); f.Graphics.ResetTransform(); #endif f.FillPolygon(_pNorthNeedleBrush, needleNorth); f.DrawPolygon(_pNorthNeedlePen, needleNorth); f.FillPolygon(_pSouthNeedleBrush, needleSouth); f.DrawPolygon(_pSouthNeedlePen, needleSouth); }
/// <summary> /// This method is called whenever the control must be rendered. All rendering takes /// place off-screen, which prevents flickering. The "PolarControl" base class automatically /// handles tasks such as resizing and smoothing. All you have to be concerned with is /// calculating the polar coordinates to draw. /// </summary> /// <param name="e"></param> protected override void OnPaintOffScreen(PaintEventArgs e) { /* The DotSpatial.Positioning comes with a special class named "PolarGraphics," which works * almost identically to the "Graphics" class, except that coordinates are given * in polar form instead of (X, Y). * * Polar coordinates are given as an angle and a radius. The angle is between 0° * and 360° clockwise from the top of the control. The radius is zero (0) at the * center of the control, and 100 at the outer edge. So, a polar coordinate of 90° * with a radius of 50 would mark a point straight to the right, half way to the * edge. Mastering polar coordinates gives you the opportunity to create your * own controls. */ // Make a PolarGraphics class for easier drawing using polar coordinates PolarGraphics f = CreatePolarGraphics(e.Graphics); #region Drawing of Tick Marks // Draw sixty small tick marks around the control for (double value = 0; value < 60; value += 1) { // There are 120 tick marks in 360° Angle angle = new Angle(value * (360 / 60)); // Get the coordinate of the line's start and end PolarCoordinate start = new PolarCoordinate(96, angle, Azimuth.North, PolarCoordinateOrientation.Clockwise); PolarCoordinate end = new PolarCoordinate(100, angle, Azimuth.North, PolarCoordinateOrientation.Clockwise); // And draw a line f.DrawLine(_pMinorTickPen, start, end); } // Draw twelve tick marks for (double value = 1; value <= 12; value += 1) { // Convert the value to an angle Angle angle = new Angle(value * (360 / 12)); // Get the coordinate of the line's start PolarCoordinate start = new PolarCoordinate(93, angle, Azimuth.North, PolarCoordinateOrientation.Clockwise); PolarCoordinate end = new PolarCoordinate(100, angle, Azimuth.North, PolarCoordinateOrientation.Clockwise); // And draw the tick mark f.DrawLine(_pMajorTickPen, start, end); // Label the clock position around the circle if (_pHoursFont != null) { string s = Convert.ToString(value, CultureInfo.CurrentUICulture); f.DrawCenteredString(s, _pHoursFont, _pValueLabelBrush, new PolarCoordinate(85, angle, Azimuth.North, PolarCoordinateOrientation.Clockwise)); } } #endregion /* In order to make the control more appealing, we'll make the hours, minutes, and * seconds hand as accurate as possible. For example, if the time is 5:30, the hours * hand should be halfway between 5 and 6, or 5.5. To get these values, we'll * calculate "fractional" hours, minutes and seconds using the TimeSpan structure. * * when you look at the control, you'll see that the minutes hand moves slowly but * smoothly as time progresses. With smoothing enabled, you almost can't tell it's * actually moving. */ // Calculate the time elapsed since midnight DateTime midnight = new DateTime(_pValue.Year, _pValue.Month, _pValue.Day); TimeSpan timeSinceMidnight = _pValue.Subtract(midnight); #region Drawing of Hours // There are twelve hours in 360° of a circle Angle hourAngle = new Angle(timeSinceMidnight.TotalHours * (360 / 12)); // Draw the hour "needle" f.DrawLine(_pHoursPen, PolarCoordinate.Center, new PolarCoordinate(30, hourAngle, Azimuth.North, PolarCoordinateOrientation.Clockwise)); #endregion #region Drawing of Minutes // There are sixty minutes in 360° of a circle Angle minuteAngle = new Angle(timeSinceMidnight.TotalMinutes * (360 / 60)); // Draw the Minute "needle" f.DrawLine(_pMinutesPen, PolarCoordinate.Center, new PolarCoordinate(80, minuteAngle, Azimuth.North, PolarCoordinateOrientation.Clockwise)); #endregion #region Drawing of Seconds // There are sixty seconds in 360° of a circle Angle secondAngle = new Angle(timeSinceMidnight.TotalSeconds * (360 / 60)); // Draw the Seconds "needle" f.DrawLine(_pSecondsPen, PolarCoordinate.Center, new PolarCoordinate(90, secondAngle, Azimuth.North, PolarCoordinateOrientation.Clockwise)); #endregion }
/// <inheritdocs/> protected override void OnPaintOffScreen(PaintEventArgs e) { PolarGraphics f = CreatePolarGraphics(e.Graphics); // What altitude are we drawing? #if PocketPC Speed SpeedToRender = pSpeed; #else Speed speedToRender = new Speed(_valueInterpolator[_interpolationIndex], _pSpeed.Units); #endif // Cache drawing intervals and such to prevent a race condition double minorInterval = _pMinorTickInterval.Value; double majorInterval = _pMajorTickInterval.Value; double cachedSpeedLabelInterval = _pSpeedLabelInterval.ToUnitType(_pMaximumSpeed.Units).Value; Speed maxSpeed = _pMaximumSpeed.Clone(); double minorStep = _pMinorTickInterval.ToUnitType(_pMaximumSpeed.Units).Value; double majorStep = _pMajorTickInterval.ToUnitType(_pMaximumSpeed.Units).Value; // Draw tick marks double angle; PolarCoordinate start; PolarCoordinate end; #region Draw minor tick marks if (minorInterval > 0) { for (double speed = 0; speed < maxSpeed.Value; speed += minorStep) { // Convert the speed to an angle angle = speed * _conversionFactor + _pMinimumAngle.DecimalDegrees; // Get the coordinate of the line's start start = new PolarCoordinate(95, angle, Azimuth.South, PolarCoordinateOrientation.Clockwise); end = new PolarCoordinate(100, angle, Azimuth.South, PolarCoordinateOrientation.Clockwise); // And draw a line Pen p = new Pen(_minorTickPenColor); f.DrawLine(p, start, end); p.Dispose(); } } #endregion #region Draw major tick marks if (majorInterval > 0) { using (Pen majorPen = new Pen(_majorTickPenColor)) { for (double speed = 0; speed < maxSpeed.Value; speed += majorStep) { // Convert the speed to an angle angle = speed * _conversionFactor + _pMinimumAngle.DecimalDegrees; // Get the coordinate of the line's start start = new PolarCoordinate(90, angle, Azimuth.South, PolarCoordinateOrientation.Clockwise); end = new PolarCoordinate(100, angle, Azimuth.South, PolarCoordinateOrientation.Clockwise); // And draw a line f.DrawLine(majorPen, start, end); } #region Draw a major tick mark at the maximum speed // Convert the speed to an angle angle = maxSpeed.Value * _conversionFactor + _pMinimumAngle.DecimalDegrees; // Get the coordinate of the line's start start = new PolarCoordinate(90, angle, Azimuth.South, PolarCoordinateOrientation.Clockwise); end = new PolarCoordinate(100, angle, Azimuth.South, PolarCoordinateOrientation.Clockwise); // And draw a line f.DrawLine(majorPen, start, end); #endregion } } #endregion using (SolidBrush fontBrush = new SolidBrush(_speedLabelBrushColor)) { if (cachedSpeedLabelInterval > 0) { for (double speed = 0; speed < maxSpeed.Value; speed += cachedSpeedLabelInterval) { // Convert the speed to an angle angle = speed * _conversionFactor + _pMinimumAngle.DecimalDegrees; // And draw a line f.DrawCenteredString(new Speed(speed, maxSpeed.Units).ToString(_pSpeedLabelFormat, CultureInfo.CurrentCulture), Font, fontBrush, new PolarCoordinate(75, angle, Azimuth.South, PolarCoordinateOrientation.Clockwise)); } // Convert the speed to an angle angle = maxSpeed.Value * _conversionFactor + _pMinimumAngle.DecimalDegrees; // And draw the speed label f.DrawCenteredString(maxSpeed.ToString(_pSpeedLabelFormat, CultureInfo.CurrentCulture), Font, fontBrush, new PolarCoordinate(75, angle, Azimuth.South, PolarCoordinateOrientation.Clockwise)); } // Draw the units for the speedometer if (_pIsUnitLabelVisible) { f.DrawCenteredString(_pMaximumSpeed.ToString("u", CultureInfo.CurrentCulture), Font, fontBrush, new PolarCoordinate(90, Angle.Empty, Azimuth.South, PolarCoordinateOrientation.Clockwise)); } } PolarCoordinate[] needle = new PolarCoordinate[_speedometerNeedle.Length]; for (int index = 0; index < needle.Length; index++) { needle[index] = _speedometerNeedle[index].Rotate((speedToRender.ToUnitType(_pMaximumSpeed.Units).Value *_conversionFactor) + _pMinimumAngle.DecimalDegrees); } // Draw an ellipse at the center f.DrawEllipse(Pens.Gray, PolarCoordinate.Empty, 10); #if !PocketPC // Now draw a shadow f.Graphics.TranslateTransform(_pNeedleShadowSize.Width, _pNeedleShadowSize.Height, MatrixOrder.Append); using (Brush b = new SolidBrush(_needleShadowBrushColor)) f.FillPolygon(b, needle); f.Graphics.ResetTransform(); #endif // Then draw the actual needle using (SolidBrush needleFill = new SolidBrush(_needleFillColor)) f.FillPolygon(needleFill, needle); using (Pen needlePen = new Pen(_needleOutlineColor)) f.DrawPolygon(needlePen, needle); }
/// <inheritdocs/> protected override void OnPaintOffScreen(PaintEventArgs e) { PolarGraphics f = CreatePolarGraphics(e.Graphics); // What altitude are we drawing? Distance altitudeToRender = new Distance(_valueInterpolator[_interpolationIndex], _altitude.Units); // There are 100 tick marks in 360 degrees. 3.6° per tick mark const double conversionFactor = 3.6; // Draw tick marks if (_minorTickPen != null) { for (double alt = 0; alt < 100; alt += 1) { // Convert the speed to an angle Angle angle = new Angle(alt * conversionFactor); // Get the coordinate of the line's start PolarCoordinate start = new PolarCoordinate(95, angle, Azimuth.North, PolarCoordinateOrientation.Clockwise); PolarCoordinate end = new PolarCoordinate(100, angle, Azimuth.North, PolarCoordinateOrientation.Clockwise); // And draw a line f.DrawLine(_minorTickPen, start, end); } } // Draw tick marks if (_majorTickPen != null) { for (double alt = 0; alt < 100; alt += 10) { // Convert the speed to an angle Angle angle = new Angle(alt * conversionFactor); // Get the coordinate of the line's start PolarCoordinate start = new PolarCoordinate(94, angle, Azimuth.North, PolarCoordinateOrientation.Clockwise); PolarCoordinate end = new PolarCoordinate(100, angle, Azimuth.North, PolarCoordinateOrientation.Clockwise); // And draw a line f.DrawLine(_majorTickPen, start, end); // And also a string string s = Convert.ToString(alt * 0.1, CultureInfo.CurrentCulture); f.DrawCenteredString(s, _altitudeLabelFont, _altitudeLabelBrush, new PolarCoordinate(85, angle, Azimuth.North, PolarCoordinateOrientation.Clockwise)); } } // Calculate all needle values double pTensOfThousandsValue = altitudeToRender.Value / 1000.0; double pThousandsValue = altitudeToRender.Value / 100.0; double pValue = altitudeToRender.Value / 10.0; // Now draw the tens-of-thousands needle // Rotate the needle to the right place PolarCoordinate[] needle1 = new PolarCoordinate[_tensOfThousandsNeedle.Length]; for (int index = 0; index < needle1.Length; index++) { needle1[index] = _tensOfThousandsNeedle[index].Rotate(pTensOfThousandsValue * conversionFactor); } // Now draw the tens-of-thousands needle // Rotate the needle to the right place PolarCoordinate[] needle2 = new PolarCoordinate[_thousandsNeedle.Length]; for (int index = 0; index < needle2.Length; index++) { needle2[index] = _thousandsNeedle[index].Rotate(pThousandsValue * conversionFactor); } // Now draw the tens-of-Hundreds needle // Rotate the needle to the right place PolarCoordinate[] needle3 = new PolarCoordinate[_hundredsNeedle.Length]; for (int index = 0; index < needle3.Length; index++) { needle3[index] = _hundredsNeedle[index].Rotate(pValue * conversionFactor); } string altitudeString = altitudeToRender.ToString(_valueFormat, CultureInfo.CurrentCulture); //SizeF FontSize = f.Graphics.MeasureString(AltitudeString, pValueFont); f.DrawRotatedString(altitudeString, _valueFont, _valueBrush, new PolarCoordinate(45.0f, Angle.Empty, Azimuth.North, PolarCoordinateOrientation.Clockwise)); // Draw an ellipse at the center f.DrawEllipse(_centerPen, PolarCoordinate.Empty, 10); f.Graphics.TranslateTransform(_needleShadowSize.Width, _needleShadowSize.Height, MatrixOrder.Append); f.FillPolygon(_needleShadowBrush, needle1); f.FillPolygon(_needleShadowBrush, needle2); f.FillPolygon(_needleShadowBrush, needle3); f.Graphics.ResetTransform(); f.FillPolygon(_tensOfThousandsBrush, needle1); f.DrawPolygon(_tensOfThousandsPen, needle1); f.FillPolygon(_thousandsBrush, needle2); f.DrawPolygon(_thousandsPen, needle2); f.FillPolygon(_hundredsBrush, needle3); f.DrawPolygon(_hundredsPen, needle3); // Draw an ellipse at the center f.FillEllipse(_hundredsBrush, PolarCoordinate.Empty, 7); f.DrawEllipse(_hundredsPen, PolarCoordinate.Empty, 7); }