0,0 → 1,153 |
/******************************************* |
Original Source by Chootair (http://www.codeproject.com/Articles/27411/C-Avionic-Instrument-Controls) |
C# Avionic Instrument Controls |
|
Made some modifications: |
--Reduced to the heading indicator |
-- & changed class to UserControl |
--changed the images |
--doublebuffered to reduce flickering |
*******************************************/ |
|
using System; |
using System.Collections.Generic; |
using System.ComponentModel; |
using System.Drawing; |
using System.Data; |
using System.Text; |
using System.Windows.Forms; |
|
namespace AvionicsInstrumentControl |
{ |
public partial class HeadingIndicator : UserControl |
{ |
public HeadingIndicator() |
{ |
InitializeComponent(); |
this.DoubleBuffered = true; |
} |
protected void RotateImage(PaintEventArgs pe, Image img, Double alpha, Point ptImg, Point ptRot, float scaleFactor) |
{ |
double beta = 0; // Angle between the Horizontal line and the line (Left upper corner - Rotation point) |
double d = 0; // Distance between Left upper corner and Rotation point) |
float deltaX = 0; // X componant of the corrected translation |
float deltaY = 0; // Y componant of the corrected translation |
|
// Compute the correction translation coeff |
if (ptImg != ptRot) |
{ |
// |
if (ptRot.X != 0) |
{ |
beta = Math.Atan((double)ptRot.Y / (double)ptRot.X); |
} |
|
d = Math.Sqrt((ptRot.X * ptRot.X) + (ptRot.Y * ptRot.Y)); |
|
// Computed offset |
deltaX = (float)(d * (Math.Cos(alpha - beta) - Math.Cos(alpha) * Math.Cos(alpha + beta) - Math.Sin(alpha) * Math.Sin(alpha + beta))); |
deltaY = (float)(d * (Math.Sin(beta - alpha) + Math.Sin(alpha) * Math.Cos(alpha + beta) - Math.Cos(alpha) * Math.Sin(alpha + beta))); |
} |
|
// Rotate image support |
pe.Graphics.RotateTransform((float)(alpha * 180 / Math.PI)); |
|
// Dispay image |
pe.Graphics.DrawImage(img, (ptImg.X + deltaX) * scaleFactor, (ptImg.Y + deltaY) * scaleFactor, img.Width * scaleFactor, img.Height * scaleFactor); |
|
// Put image support as found |
pe.Graphics.RotateTransform((float)(-alpha * 180 / Math.PI)); |
|
} |
#region Fields |
|
// Parameters |
int Heading; |
|
// Images |
Bitmap bmpHedingWeel = new Bitmap(AvionicsInstrumentControl.Properties.Resources.HeadingIndicatorOverlay); |
Bitmap bmpAircaft = new Bitmap(AvionicsInstrumentControl.Properties.Resources.HeadingIndicatorBackground); |
|
#endregion |
|
#region Paint |
|
protected override void OnPaint(PaintEventArgs pe) |
{ |
// Calling the base class OnPaint |
base.OnPaint(pe); |
|
// Pre Display computings |
Point ptRotation = new Point(200, 200); |
Point ptImgAircraft = new Point(0, 0); |
Point ptImgHeadingWeel = new Point(0, 0); |
|
double alphaHeadingWeel = InterpolPhyToAngle(Heading, 0, 360, 360, 0); |
|
float scale = (float)this.Width / (bmpHedingWeel.Width); |
|
pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; |
|
// display aircraft |
pe.Graphics.DrawImage(bmpAircaft, (int)(ptImgAircraft.X * scale), (int)(ptImgAircraft.Y * scale), (float)(bmpAircaft.Width * scale), (float)(bmpAircaft.Height * scale)); |
|
|
// display HeadingWeel |
RotateImage(pe, bmpHedingWeel, alphaHeadingWeel, ptImgHeadingWeel, ptRotation, scale); |
|
} |
|
#endregion |
|
#region Methods |
/// <summary> |
/// Convert a physical value in an rad angle used by the rotate function |
/// </summary> |
/// <param name="phyVal">Physical value to interpol/param> |
/// <param name="minPhy">Minimum physical value</param> |
/// <param name="maxPhy">Maximum physical value</param> |
/// <param name="minAngle">The angle related to the minumum value, in deg</param> |
/// <param name="maxAngle">The angle related to the maximum value, in deg</param> |
/// <returns>The angle in radian witch correspond to the physical value</returns> |
protected float InterpolPhyToAngle(float phyVal, float minPhy, float maxPhy, float minAngle, float maxAngle) |
{ |
float a; |
float b; |
float y; |
float x; |
|
if (phyVal < minPhy) |
{ |
return (float)(minAngle * Math.PI / 180); |
} |
else if (phyVal > maxPhy) |
{ |
return (float)(maxAngle * Math.PI / 180); |
} |
else |
{ |
|
x = phyVal; |
a = (maxAngle - minAngle) / (maxPhy - minPhy); |
b = (float)(0.5 * (maxAngle + minAngle - a * (maxPhy + minPhy))); |
y = a * x + b; |
|
return (float)(y * Math.PI / 180); |
} |
} |
|
/// <summary> |
/// Define the physical value to be displayed on the indicator |
/// </summary> |
/// <param name="aircraftHeading">The aircraft heading in °deg</param> |
public void SetHeadingIndicatorParameters(int aircraftHeading) |
{ |
Heading = aircraftHeading; |
|
this.Refresh(); |
} |
|
#endregion |
|
} |
} |