Subversion Repositories Projects

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2233 - 1
/*******************************************
2
Original Source by Chootair (http://www.codeproject.com/Articles/27411/C-Avionic-Instrument-Controls)
3
C# Avionic Instrument Controls
4
 
5
Made some modifications:
6
--Reduced to the heading indicator
7
-- & changed class to UserControl
8
--changed the images
9
--doublebuffered to reduce flickering
10
*******************************************/
11
 
12
using System;
13
using System.Collections.Generic;
14
using System.ComponentModel;
15
using System.Drawing;
16
using System.Data;
17
using System.Text;
18
using System.Windows.Forms;
19
 
20
namespace AvionicsInstrumentControl
21
{
22
    public partial class HeadingIndicator : UserControl
23
    {
24
        public HeadingIndicator()
25
        {
26
            InitializeComponent();
27
            this.DoubleBuffered = true;
28
        }
29
        protected void RotateImage(PaintEventArgs pe, Image img, Double alpha, Point ptImg, Point ptRot, float scaleFactor)
30
        {
31
            double beta = 0;    // Angle between the Horizontal line and the line (Left upper corner - Rotation point)
32
            double d = 0;               // Distance between Left upper corner and Rotation point)               
33
            float deltaX = 0;   // X componant of the corrected translation
34
            float deltaY = 0;   // Y componant of the corrected translation
35
 
36
            // Compute the correction translation coeff
37
            if (ptImg != ptRot)
38
            {
39
                //
40
                if (ptRot.X != 0)
41
                {
42
                    beta = Math.Atan((double)ptRot.Y / (double)ptRot.X);
43
                }
44
 
45
                d = Math.Sqrt((ptRot.X * ptRot.X) + (ptRot.Y * ptRot.Y));
46
 
47
                // Computed offset
48
                deltaX = (float)(d * (Math.Cos(alpha - beta) - Math.Cos(alpha) * Math.Cos(alpha + beta) - Math.Sin(alpha) * Math.Sin(alpha + beta)));
49
                deltaY = (float)(d * (Math.Sin(beta - alpha) + Math.Sin(alpha) * Math.Cos(alpha + beta) - Math.Cos(alpha) * Math.Sin(alpha + beta)));
50
            }
51
 
52
            // Rotate image support
53
            pe.Graphics.RotateTransform((float)(alpha * 180 / Math.PI));
54
 
55
            // Dispay image
56
            pe.Graphics.DrawImage(img, (ptImg.X + deltaX) * scaleFactor, (ptImg.Y + deltaY) * scaleFactor, img.Width * scaleFactor, img.Height * scaleFactor);
57
 
58
            // Put image support as found
59
            pe.Graphics.RotateTransform((float)(-alpha * 180 / Math.PI));
60
 
61
        }
62
        #region Fields
63
 
64
        // Parameters
65
        int Heading;
66
 
67
        // Images
68
        Bitmap bmpHedingWeel = new Bitmap(AvionicsInstrumentControl.Properties.Resources.HeadingIndicatorOverlay);
69
        Bitmap bmpAircaft = new Bitmap(AvionicsInstrumentControl.Properties.Resources.HeadingIndicatorBackground);
70
 
71
        #endregion
72
 
73
        #region Paint
74
 
75
        protected override void OnPaint(PaintEventArgs pe)
76
        {
77
            // Calling the base class OnPaint
78
            base.OnPaint(pe);
79
 
80
            // Pre Display computings
81
            Point ptRotation = new Point(200, 200);
82
            Point ptImgAircraft = new Point(0, 0);
83
            Point ptImgHeadingWeel = new Point(0, 0);
84
 
85
            double alphaHeadingWeel = InterpolPhyToAngle(Heading, 0, 360, 360, 0);
86
 
87
            float scale = (float)this.Width / (bmpHedingWeel.Width);
88
 
89
            pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
90
 
91
            // display aircraft
92
            pe.Graphics.DrawImage(bmpAircaft, (int)(ptImgAircraft.X * scale), (int)(ptImgAircraft.Y * scale), (float)(bmpAircaft.Width * scale), (float)(bmpAircaft.Height * scale));
93
 
94
 
95
            // display HeadingWeel
96
            RotateImage(pe, bmpHedingWeel, alphaHeadingWeel, ptImgHeadingWeel, ptRotation, scale);
97
 
98
        }
99
 
100
        #endregion
101
 
102
        #region Methods
103
        /// <summary>
104
        /// Convert a physical value in an rad angle used by the rotate function
105
        /// </summary>
106
                /// <param name="phyVal">Physical value to interpol/param>
107
                /// <param name="minPhy">Minimum physical value</param>
108
                /// <param name="maxPhy">Maximum physical value</param>
109
                /// <param name="minAngle">The angle related to the minumum value, in deg</param>
110
                /// <param name="maxAngle">The angle related to the maximum value, in deg</param>
111
                /// <returns>The angle in radian witch correspond to the physical value</returns>
112
        protected float InterpolPhyToAngle(float phyVal, float minPhy, float maxPhy, float minAngle, float maxAngle)
113
        {
114
            float a;
115
            float b;
116
            float y;
117
            float x;
118
 
119
            if (phyVal < minPhy)
120
            {
121
                return (float)(minAngle * Math.PI / 180);
122
            }
123
            else if (phyVal > maxPhy)
124
            {
125
                return (float)(maxAngle * Math.PI / 180);
126
            }
127
            else
128
            {
129
 
130
                x = phyVal;
131
                a = (maxAngle - minAngle) / (maxPhy - minPhy);
132
                b = (float)(0.5 * (maxAngle + minAngle - a * (maxPhy + minPhy)));
133
                y = a * x + b;
134
 
135
                return (float)(y * Math.PI / 180);
136
            }
137
        }
138
 
139
        /// <summary>
140
        /// Define the physical value to be displayed on the indicator
141
        /// </summary>
142
        /// <param name="aircraftHeading">The aircraft heading in °deg</param>
143
        public void SetHeadingIndicatorParameters(int aircraftHeading)
144
        {
145
            Heading = aircraftHeading;
146
 
147
            this.Refresh();
148
        }
149
 
150
        #endregion
151
 
152
    }
153
}