12,626,106 members (33,506 online)
alternative version

89.8K views
36 bookmarked
Posted

# CStatic derivative CSpeedoMeter class

, 22 Jan 2005
 Rate this:
A simple SpeedoMeter class based on CStatic base class.

## Introduction

Here is a Speedometer class, `CSpeedoMeter` v1.0. I had been looking for a speedometer control out there for a while but I couldn’t find one. Then I decided to give it a try. I thought it would be pretty simple, using simple trigonometric calculation to do rotation. If you are wondering why you need a rotation calculation, imagine you are in front of your car's dashboard. When you press the pedal you will see something rotating and suddenly your car starts accelerating. Exactly, you need to rotate a needle!

Basically, my approach is to have the background of the speedometer as a bitmap. Unfortunately, to make the needle as a bitmap is a bit messy. There is not an easy way to rotate bitmap in GDI API. But, we can just draw the needle as a line. You only need to take care of two points, while you connect with a straight line. In fact, you are actually controlling only one point. That point will be rotated and a line segment will be drawn representing the needle at any particular speed. Simple enough!

## The Simple Mathematics

To make it happen, you need to calibrate your Speedo's needle. I am assuming the 0 degree start from 6 o’clock. As with most of the real Speedo controls in a real car, the needle is initially set at about 7:00 o’clock direction (30 degree clock-wise from 6 o’clock. Our example however uses initial offset at 40 degree). Remember, one full circle would represent 360 degrees. If let’s say, we assume one degree will represent 1 km/h, then life is easy. For each 1 km/h delta, it will represent a rotation of 1 degree clock-wise.

Therefore, once we can calculate the rotation and are able to draw the needle at any particular angle, then that’s about it, a speedometer is not far away from your hand. We just need to make some assumptions. So, for example let’s say, updating the needle to 240 km/h, you need to rotate the needle by 240 degrees + offset. Remember we use offset = 40, which makes the rotation required to set the needle to 240 km/h, to 280 degrees. The basic formula is:

RotationAngle = OffsetAngle + NewSpeed;

I am sure it is simple enough to be understood, so I would just teach you how to use my control. Another thing worth mentioning is, don’t forget about drawing the appropriate background image that is consistent with your assumption. In my case, I created a bitmap with the 0 speed set at 40 degrees from 6 o’clock clock-wise. I know my bitmap is not the coolest in this planet, but to make a start I think it is not too bad, yeah!

## Using the code

There are a few files you need to copy to your project directory. They are:-

• matrix2x2.h & matrix2x2.cpp
• vector2.h & vector2.cpp
• speedometer.h & speedometer.cpp

The matrix2x2 and vector2 are also written by me for doing the rotation stuff. They become so handy from time to time when I develop various projects. The speedometer class is obviously the core engine of the Speedo.

After you put them in your project directory, create a dialog MFC project and add the above files to the project. Then, just build the project. I am sure it will fail. Why? Because you haven’t linked your project with winmm.lib. Please do so by going to Project-><ProjectName> Properties…

Go to linker and add winmm.lib on Additional Dependencies field. Just wanna inform you, I use Visual Studio .NET 2003 to build the project. For VS 6, please refer to VS documentation on how to link libraries to your project.

Next, you need to create a static control on your dialog. Size it to 400x400 to fit my bitmap background. Add a control variable to the static control, say `m_speedometer`. Then under your XXXDlg.h, change the type of `m_speedmeter` control from `CStatic` to `CSpeedoMeter`. Don’t forget to add `#include speedometer.h` at the top of your XXXDlg.h file to make sure it understands what `CSpeedoMeter` does.

Wait a minute, you are still 2-3 steps away from using the control. The next step would be to initialize the speedometer. To do this, I prefer to create an initialization function in your `XXXDlg` (in my demo example, it is `CspeedoMeterDlg`) class, say `void InitializeSpeedoMeter()`. Add a few lines of code to the function body to set the bitmap, needle thickness, and its color. You should call the initialization routine inside the `OnInitDialog()` handler.

```// Initialization code
void CSpeedoMeterDlg::InitSpeedoMeter()
{
m_speedometer.SetBitmap(IDB_SPEEDOMETER);
m_speedometer.SetNeedleThickness(5);
m_speedometer.SetNeedleColor(RGB(255,0,0));
}```

I am assuming that you know how to import a bitmap to your project. Otherwise, simply go to Project->Add Resource on the main menu, then import bitmap. Don’t forget to name the bitmap (e.g., `IDB_SPEEDOMETER`). Last but not the least, call `InitSpeedoMeter` in the `OnInitDialog()` handler, just under `// TODO: Add extra initialization here`.

OK, now you are ready to use the control. One easy way to try the control is to add `OnMouseWheel(…)` handler. Then based on the value of `zDelta`, you update the speedometer speed through `UpdateSpeed(float speed)` interface or `Accelerationg(float delta)` interface. My demo, uses `OnTimer(…)` handler to do a simple but interesting simulation.

## Points of Interest

Doing graphics programming is always exciting because no matter what, you will play with math, and if you are lucky, you will play with physics. It is so cool!. Any, constructive input, comments and expression of interest can be sent to my email address.

## History

• V1.0 - Working speedometer.

A list of licenses authors might use can be found here

## Share

 Software Developer United States
Henry Tan was born in a small town, Sukabumi, Indonesia, on December 7th, 1979. He obtained his Bachelor of Computer System Engineering with first class honour from La Trobe University, VIC, Australia in 2003. During his undergraduate study, he was nominated as the most outstanding Honours Student in Computer Science. Additionally, he was the holder of 2003 ACS Student Award. After he finished his Honour year at La Trobe University, on August 2003, he continued his study pursuing his doctorate degree at UTS under supervision Prof. Tharam S. Dillon. He obtained his PhD on March 2008. His research interests include Data Mining, Computer Graphics, Game Programming, Neural Network, AI, and Software Development. On January 2006 he took the job offer from Microsoft Redmond, USA as a Software Design Engineer (SDE).

What he like most? Programming!Math!Physisc!Computer Graphics!Playing Game!

What programming language?
C/C++ but started to love C#.

## You may also be interested in...

 First Prev Next
 GDI Resource leakage darkhalf50129-Jan-06 11:23 darkhalf501 29-Jan-06 11:23
 The control is nice but a suggestion subash110721-Dec-05 21:34 subash1107 21-Dec-05 21:34
 The name of the subclass Alex Evans19-Feb-05 19:25 Alex Evans 19-Feb-05 19:25
 A Few Comments Rick York25-Jan-05 9:12 Rick York 25-Jan-05 9:12
 Re: A Few Comments Henry Tan17-Mar-05 17:05 Henry Tan 17-Mar-05 17:05
 Last Visit: 31-Dec-99 19:00     Last Update: 5-Dec-16 13:23 Refresh 1