Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 2232 → Rev 2233

/MKLiveView/AvionicsInstrumentControl/HeadingIndicator.cs
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
 
}
}