Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Simulation of a Canadian F-86 Fighter Jet in Windows Forms using Visual C++ 2005

0.00/5 (No votes)
30 May 2010 1  
A Simulation of a Canadian F-86 fighter jet in Windows Forms using Visual C++ 2005

Introduction

Why am I creating a simulation of an aircraft's flight instruments? The reason is because I grew up surrounded by jet and turboprop aircrafts and I've always wanted to replicate the dynamics of aircrafts on software.

The North American Aviation F-86 Sabre

The F-86 Sabre is a fighter aircraft. Sabre is best known for its Korean War against the Soviet MiG-15. There have been more than 7,800 aircrafts between 1949 and 1956 and were by far the most-produced Western jet fighters, with a total production of all variants at 9,860 units. Variants were built in Canada and Australia. The Canadair Sabre added another 1,815 airframes, and the significantly redesigned CAC Sabre (sometimes known as the Avon Sabre or CAC CA-27), had a production run of 112.

Specifications (F-86A):

Armament: Six .50-cal. machine guns and eight 5-in. rockets or 2,000 lbs. of bombs
Engine: One General Electric J47 turbojet of 5,200 lbs. thrust
Maximum speed: 685 mph
Cruising speed: 540 mph
Range: 1,200 miles
Combat ceiling: 49,000 ft.
Span: 37 ft. 1 in.
Length: 37 ft. 6 in.
Height: 14 ft. 8 in.
Weight: 13,791 lbs. loaded
Crew: One

Fast Forwarding a Bit

Designing apps in Microsoft Visual C++ 2005 Express Edition is pretty straight forward. Point this, click that, presto! Place it on the form. Components on the form align to rectangular grids, giving your apps a symmetric look.

Fast forwarding a bit, we've created a Windows Form, placed labels and pictureboxes on the form to have all these controls respond to mouse clicks, and key events, we have to put some code into it. So we double-click on any given control, place some code in that controls' event method.

KeyDown Event

The KeyDown event is called upon when a key is pressed down. The flight instruments and gauges respond accordingly by displaying the changes on the instruments. So when the user presses down the left, right, up or down key - the instruments and gauges will display tilting or banking.

private: System::Void KeyDown(System::Object^  sender, 
	System::Windows::Forms::KeyEventArgs^  e)
{
	switch(e->KeyCode)
	{
		case System::Windows::Forms::Keys::Enter :
		break;

		case System::Windows::Forms::Keys::PageUp :
			rpm =rpm + delta_rpm; filter_rpm();
		break; //pgup

		case System::Windows::Forms::Keys::PageDown :
			rpm =rpm - delta_rpm;  filter_rpm();
		break;//pgdn

		case System::Windows::Forms::Keys::Up :
			alpha_tail =alpha_tail - delta_elevator;
			if (alpha_tail < -max_alpha_tail) alpha_tail  =   
							-max_alpha_tail;
		break;  //UpArw

		case System::Windows::Forms::Keys::Down :
			alpha_tail =alpha_tail + delta_elevator;
			if (alpha_tail > max_alpha_tail) alpha_tail   =   
							max_alpha_tail;
		break; //{ DwnArw }

		case System::Windows::Forms::Keys::Left  :
			alpha_aileron =alpha_aileron - (delta_aileron*rTrim);
			if (alpha_aileron < -max_aileron)  alpha_aileron  =  
							-max_aileron;
		break;    // { LftArw }

		case  System::Windows::Forms::Keys::Right :
			alpha_aileron =alpha_aileron + (delta_aileron*rTrim);
			if (alpha_aileron >max_aileron)  alpha_aileron   =   
							max_aileron;
		break; //   { RtArw }

		case  System::Windows::Forms::Keys::End :
			revertToInitialParameters();  ;
			break;//    { End }
		case  System::Windows::Forms::Keys::Home :// { Home }
					initialize_variables();

		break;

		case System::Windows::Forms::Keys::R 
				:/*set_rpm()*/; break; //  'R' : set_rpm();
		case System::Windows::Forms::Keys::P 
				:/*set_pitch()*/; break; //  'P' : set_pitch();
		case System::Windows::Forms::Keys::E
				:/*set_elevator()*/; break; //  'E' : set_elevator();
		case System::Windows::Forms::Keys::A 
				:/*set_aileron()*/;break;  //  'A' : set_aileron();
		case System::Windows::Forms::Keys::S 
				:/* set_mach()*/;break; //  'S' : set_mach();
		case System::Windows::Forms::Keys::W 
				:/*set_weight()*/; break; //  'W' : set_weight();
		case System::Windows::Forms::Keys::B 
				:/* set_bank()*/;break; //  'B' : set_bank();
		case 102:/*set_altitude()*/; break; //  'F' : set_altitude();
		case 104:/*set_heading()*/;break;  //  'H' : set_heading();
		case System::Windows::Forms::Keys::L:set_level(); 	
				break; //  'L' : set_level();
		case System::Windows::Forms::Keys::T: set_trim();
				break; //  'T' : set_trim();
		case System::Windows::Forms::Keys::Tab:debugon=-debugon;break;
	}
}

MouseMove Event

The MouseMove event is called upon when the mouse is dragged or moved. The flight instruments and gauges respond accordingly by displaying the changes on the instruments. So when the mouse moves up, down, left, right, - the instruments and gauges will display the movements accordingly.

private: System::Void pictureBox1_MouseMove
	(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e)
{
	label26->Text=L"mx= "+System::Convert::ToString(e->X)+L"   
				my= "+System::Convert::ToString(e->Y);
	oldMouseX = mouseX;	oldMouseY = mouseY;	
				mouseX = e->X;	mouseY = e->Y;
	if (mouseNavigationEnabled)
	{
		if ((mouseX - oldMouseX) > 0)
		{
			 alpha_aileron =alpha_aileron + (delta_aileron*10);
			 if (alpha_aileron >max_aileron)  
			  alpha_aileron   =   max_aileron;// mouse moved to the right
		}
		else if ((mouseX - oldMouseX) < 0)
		{
			alpha_aileron =alpha_aileron - (delta_aileron*10);
			if (alpha_aileron < -max_aileron)  
			  alpha_aileron  =  -max_aileron;// mouse moved to the left
		}

		if ((mouseY - oldMouseY) > 0)
		{
			 alpha_tail =alpha_tail + (delta_elevator*10);
			 if (alpha_tail > max_alpha_tail) 
			  alpha_tail   =   max_alpha_tail; // mouse moved to the DOWN
		}
		else if ((mouseY - oldMouseY) < 0)
		{
			 alpha_tail =alpha_tail - (delta_elevator*10);
			 if (alpha_tail < -max_alpha_tail) 
			  alpha_tail  =   -max_alpha_tail; // mouse moved to the UP
		}
	}
}

The pictureBox1_Paint Event

The pictureBox1_Paint event is called upon to draw the gauges and instruments.

private: System::Void pictureBox1_Paint(System::Object^  sender, 
			System::Windows::Forms::PaintEventArgs^  e)
{
	horizon_bar(e);
	horizon_bar(e);
	alt_needle(e);
	t_and_b_needle(e);
	hsi_heading(e);
	rofc_needle(e);
	fuelflow_value(e);
	rpm_needle( e);
	draw_rpm( rpm_x,rpm_y, e);
	rpm_needle( e);
	rpmmeter(e);
	draw_n(e);
	draw_mach( );
	draw_tas(e);
	draw_ias(ias_x, ias_y, e);
	ias_needle(e);
	airspeed(e);
	hdi(e);
	draw_altitude(alt_x, alt_y,e);
	alt_needle(e);
	altimeter(e);  /*	draw_t_and_b(tab_x,tab_y,e );	 */
	t_and_b_needle( e);
	t_and_b( e);
	draw_heading( e);
	hsi_heading( e);
	hsi(e);
	draw_hdi(e);
	draw_rofc(roc_x, roc_y , e);
	rofc_needle(e);
	rofc( e);
	draw_fuelflow(e);
	fuelflow_value(e);
	ias_needle(e);  d
	raw_circles(e);
}

The draw_rpm( ) Method

The draw_rpm( ) method is called upon to display when the user increases the throttle to give it more gas, the needle in the RPM meter will respond accordingly.

void gaugeSimulator::draw_rpm(int x, int y , PaintEventArgs^ e)
{
	label25->Text=L"rpmx="+System::Convert::ToString(rpm_x)+L", 
		rpmy=  "+System::Convert::ToString(rpm_y)+L",  
		x="+System::Convert::ToString(x)+L", y="+ System::Convert::ToString(y);
	rpm_last  =rpm;
	 e->Graphics->DrawLine( lineColor, rpm_x, rpm_y, x, y);
	rpm_lastx =x;
	rpm_lasty =y;
  //
} 

The rpm_needle( PaintEventArgs^ e)

The rpm_needle( PaintEventArgs^ e) method is called upon to draw the needle of an RPM meter.

void gaugeSimulator::rpm_needle( PaintEventArgs^ e)
{
  double   x, y ;
  double z  ;

	z =rpm * (max_engine_rpm/100) * 16 * PI/10;
	x =rpm_x + (double)( 0.9 * rpm_r * Math::Cos(13*PI/10 - z) );
	y =rpm_y - (double)( 0.9 * rpm_r * Math::Sin(13*PI/10 - z) * gAR );

	label24->Text=L"rpmx="+System::Convert::ToString(rpm_x)+L", 
		rpmy=  "+System::Convert::ToString(rpm_y)+L",  
		x="+System::Convert::ToString(rpm_lastx)+L", 
		y="+ System::Convert::ToString(rpm_lasty);
	if  ( (Math::Abs(rpm_lastx - x) > 0)  ||  (Math::Abs(rpm_lasty - y) > 0) )
	{
	  e->Graphics->DrawLine( lineColor, rpm_x, rpm_y, rpm_lastx, rpm_lasty);
	  draw_rpm((int)x, (int)y+17,e);
	  label29->Text=System::Convert::ToString(Math::Round
				(rpm_last * max_engine_rpm,2));
	}
} 

Please also have a look at C# Avionic Instrument Controls[^].

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here