I changed the Horizon Bitmap so you can display a full +/-90 degree pitch angle, i.e. a loop. I had to stretch the image to include 90 degree and past that point to 60 and -60 degrees in both directions. Then I had to modify the OnPaint method as below
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
Point ptBoule = new Point(25, - 330);
Point ptRotation = new Point(150, 150);
float scale = (float)this.Width / bmpCadran.Width;
bmpCadran.MakeTransparent(Color.Yellow);
bmpAvion.MakeTransparent(Color.Yellow);
RotateAndTranslate(pe, bmpBoule, RollAngle, 0, ptBoule, (int)(4*PitchAngle), ptRotation, scale);
Pen maskPen = new Pen(this.BackColor,30*scale);
pe.Graphics.DrawRectangle(maskPen, 0, 0, bmpCadran.Width * scale, bmpCadran.Height * scale);
pe.Graphics.DrawImage(bmpCadran, 0, 0, (float)(bmpCadran.Width * scale), (float)(bmpCadran.Height * scale));
pe.Graphics.DrawImage(bmpAvion, (float)((0.5 * bmpCadran.Width - 0.5 * bmpAvion.Width) * scale), (float)((0.5 * bmpCadran.Height - 0.5 * bmpAvion.Height) * scale), (float)(bmpAvion.Width * scale), (float)(bmpAvion.Height * scale));
}
It would also be nice if the altitude digits scrolled more smoothly, instead of just on step based on the previous decade digit. e.g It should scroll for values around 10 feet before the digit must change.
This is what I did for the altimeter I did a while bac, which is fairly similar. I also use a background image to do the drawing before painting it to the current canvas. It helps with
private void Altimeter_Paint(object sender, PaintEventArgs e)
{
try
{
SolidBrush NeedleBrush = new SolidBrush(Color.Yellow);
// Draw the background Image
this.BackgroundImage = new Bitmap(this.Width, this.Height);
Graphics Background = Graphics.FromImage(this.BackgroundImage);
// Draw the dial
Background.DrawImage(this.DialImage, 0, 0);
// Draw the scrolling numbers
float imageIndex;
// First the 10s numbers
imageIndex = this.mAltitude % 100;
imageIndex = imageIndex / 10;
float lowDigit = imageIndex;
imageIndex = (imageIndex * this.DigitHeight_10) + this.DigitStart_10;
Background.DrawImage(this.TensImage, this.DigitRect_10, new Rectangle(0, (int)imageIndex, this.TensImage.Width, this.DigitRect_10.Height), GraphicsUnit.Pixel);
// Then the 100s
imageIndex = this.mAltitude / 100;
imageIndex = imageIndex % 10;
imageIndex = (float)Math.Floor(imageIndex);
imageIndex = (imageIndex * this.DigitHeight_10) + this.DigitStart_100;
// Slowly shift this digit when it reaches 90 feet
if (lowDigit > 9)
{
float shift = (lowDigit - 9) * this.DigitHeight_10;
imageIndex += shift;
}
// Draw the digit
Background.DrawImage(this.HundredsImage, this.DigitRect_100, new Rectangle(0, (int)imageIndex, this.HundredsImage.Width, this.DigitRect_100.Height), GraphicsUnit.Pixel);
// Then the 1000s
if (this.mAltitude < 990)
{
Background.DrawImage(this.FlagImage, this.DigitRect_1000, new Rectangle(0, 0, this.FlagImage.Width, this.FlagImage.Height), GraphicsUnit.Pixel);
}
else
{
imageIndex = this.mAltitude / 1000;
imageIndex = imageIndex % 10;
// Check to see this digit is moving
bool updateDigit = false;
if ((imageIndex % 1) > 0.99)
{
updateDigit = true;
}
imageIndex = (float)Math.Floor(imageIndex);
imageIndex = (imageIndex * this.DigitHeight_1000) + this.DigitStart_1000;
// Slowly shift this digit when it reaches 90 feet
if ((lowDigit > 9) && updateDigit)
{
float shift = (lowDigit - 9) * this.DigitHeight_1000;
imageIndex += shift;
}
Background.DrawImage(this.ThousandsImage, this.DigitRect_1000, new Rectangle(0, (int)imageIndex, this.ThousandsImage.Width, this.DigitRect_1000.Height), GraphicsUnit.Pixel);
}
// Finally the 10,000s, if there is no 10,000s, then display the number as flagged
if (this.mAltitude < 9990)
{
Background.DrawImage(this.FlagImage, this.DigitRect_10000, new Rectangle(0, 0, this.FlagImage.Width, this.FlagImage.Height), GraphicsUnit.Pixel);
}
else
{
imageIndex = this.mAltitude / 10000;
// Check to see this digit is moving
bool updateDigit = false;
if ((imageIndex % 1) > 0.999)
{
updateDigit = true;
}
imageIndex = (float)Math.Floor(imageIndex);
imageIndex = (imageIndex * this.DigitHeight_1000) + this.DigitStart_1000;
// Slowly shift this digit when it reaches 90 feet
if ((lowDigit > 9) && updateDigit)
{
float shift = (lowDigit - 9) * this.DigitHeight_1000;
imageIndex += shift;
}
Background.DrawImage(this.ThousandsImage, this.DigitRect_10000, new Rectangle(0, (int)imageIndex, this.ThousandsImage.Width, this.DigitRect_10000.Height), GraphicsUnit.Pixel);
}
// Draw the pointer
float altNeedleAngle = (((this.mAltitude % 100) / 100.0F) * 360.0F) - 90.0F;
// Work out the needle endpoint
Point altPoint = new Point();
altPoint.X = this.dialCentre.X + (int)Math.Round(this.NeedleLength * Math.Cos(altNeedleAngle * Math.PI / 180));
altPoint.Y = this.dialCentre.Y + (int)Math.Round(this.NeedleLength * Math.Sin(altNeedleAngle * Math.PI / 180));
Point TipPoint1 = new Point();
TipPoint1.X = this.dialCentre.X + (int)Math.Round((this.NeedleLength - 8) * Math.Cos((altNeedleAngle - 5) * Math.PI / 180));
TipPoint1.Y = this.dialCentre.Y + (int)Math.Round((this.NeedleLength - 8) * Math.Sin((altNeedleAngle - 5) * Math.PI / 180));
Point TipPoint2 = new Point();
TipPoint2.X = this.dialCentre.X + (int)Math.Round((this.NeedleLength - 8) * Math.Cos((altNeedleAngle + 5) * Math.PI / 180));
TipPoint2.Y = this.dialCentre.Y + (int)Math.Round((this.NeedleLength - 8) * Math.Sin((altNeedleAngle + 5) * Math.PI / 180));
Point TipPoint3 = new Point();
TipPoint3.X = this.dialCentre.X + (int)Math.Round(this.NeedleStart * Math.Cos(altNeedleAngle * Math.PI / 180));
TipPoint3.Y = this.dialCentre.Y + (int)Math.Round(this.NeedleStart * Math.Sin(altNeedleAngle * Math.PI / 180));
// Create the polygon with the points
Point[] altNeedle = {
altPoint, // The end of the needle
TipPoint1, // The left side pint
TipPoint3, // The inner tip point
TipPoint2 }; // The right side other side
// Draw the polygon
Background.FillPolygon(NeedleBrush, altNeedle);
// Paste the image to the control
e.Graphics.DrawImage(this.BackgroundImage, 0, 0);
// Freeup the resources
NeedleBrush.Dispose();
this.BackgroundImage.Dispose();
Background.Dispose();
}
catch (Exception ex)
{
if (ex.Message != "")
{ }
}
}
|