Actually the textual representation did not look to great. So I decided to look for a free .NET mobile compass control - which I did not find.
/// <summary>
/// Paints the control.
/// </summary>
/// <param name="e"></param>
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
int penWidth = 5;
using (Graphics g = this.CreateGraphics())
using (Pen penBlackThin = new Pen(Color.Black, penWidth - 3))
using (Pen penBlack = new Pen(Color.Black, penWidth))
using (Pen penDarkGray = new Pen(Color.DarkGray, penWidth))
using (Pen penRed = new Pen(Color.Red, penWidth + 3))
using (Pen penWhite = new Pen(Color.WhiteSmoke, penWidth + 3))
using (Brush brushDarkGray = new SolidBrush(Color.DarkGray))
using (Brush brushWhite = new SolidBrush(Color.White))
using (Brush brushLightGray = new SolidBrush(Color.LightGray))
using (Brush brushRed = new SolidBrush(Color.Red))
{
double radius = (this.ClientRectangle.Width - 50) / 2;
double radiusInner = (this.ClientRectangle.Width - 70) / 2;
int xcenter = this.ClientRectangle.Width / 2;
int ycenter = this.ClientRectangle.Height / 2;
float halfFont = this.Font.Size / 2;
// g.Clear(this.BackColor);
// draw circles
g.FillEllipse(brushLightGray, penWidth, penWidth, this.ClientRectangle.Width - 2 * penWidth, this.ClientRectangle.Height - 2 * penWidth);
g.DrawEllipse(penDarkGray, penWidth, penWidth, this.ClientRectangle.Width - 2 * penWidth, this.ClientRectangle.Height - 2 * penWidth);
g.DrawEllipse(penBlack, 2 * penWidth, 2 * penWidth, this.ClientRectangle.Width - 4 * penWidth, this.ClientRectangle.Height - 4 * penWidth);
// draw separator lines
for (int l = 0; l < 16; l++)
{
double angle = l * 22.5 + this.Heading;
double xout = Math.Sin(this.ToRadian(angle)) * radiusInner;
double yout = Math.Cos(this.ToRadian(angle)) * radiusInner;
double xin = Math.Sin(this.ToRadian(angle)) * (radiusInner - 2 * this.Font.Size);
double yin = Math.Cos(this.ToRadian(angle)) * (radiusInner - 2 * this.Font.Size);
g.DrawLine(penBlackThin, (int)xout + xcenter, (int)yout + ycenter, (int)xin + xcenter, (int)yin + ycenter);
}
// draw N, W, E, S
double x = Math.Sin(this.ToRadian(this.Heading)) * radius;
double y = Math.Cos(this.ToRadian(this.Heading)) * radius;
g.DrawString("N", this.Font, brushRed, (float)(xcenter - x) - halfFont, (float)(ycenter - y) - halfFont);
g.DrawString("S", this.Font, brushRed, (float)(xcenter + x) - halfFont, (float)(ycenter + y) - halfFont);
g.DrawString("W", this.Font, brushRed, (float)(xcenter - y) - halfFont, (float)(ycenter + x) - halfFont);
g.DrawString("E", this.Font, brushRed, (float)(xcenter + y) - halfFont, (float)(ycenter - x) - halfFont);
// draw needle
g.DrawLine(penWhite, xcenter, ycenter, xcenter, this.ClientRectangle.Height - 50);
g.DrawLine(penRed, xcenter, 50, xcenter, ycenter);
// draw digital heading
g.FillRectangle(brushWhite, (int)(xcenter - 11 * halfFont), (int)(ycenter - 5 * halfFont), (int)(22 * halfFont), (int)(11 * halfFont));
g.DrawString(string.Format("{0,3:000}°", this.Heading), this.Font, brushRed, xcenter - 4 * halfFont, ycenter - 5 * halfFont);
// draw height above sea level
g.DrawString(string.Format("{0,4:0000.0}m", this.Height), this.Font, brushRed, xcenter - 10 * halfFont, ycenter);
}
}
Needs some adjustments, especially to look great on other screen resolutions too. Maybe later ...