Sign in to follow this  
mfrantz

Vector gauges programming question

Recommended Posts

I am taking my first steps in vector gauges programming and it seems I got stuck already.Referring to the MS SDK FlightMap example :As I understand the dim variable in PIXPOINT dim = pelement->image_data.final->dim;is supposed to contain the gauge viewable area dimensions (width, height) in pixels. So the rectangle:Rectangle (hdc, 0, 0, dim.x, dim.y);should be a white line border around the gauge size.However this is not the case. When I compile and test the SDK!FlightMap on a panel this border is wrong. The height (dim.y) is double what it should be and the width (dim.x) is a bit less than the gauge width. Also the aircraft symbol is not at the center, and in general everything is misplaced.I have used TextOut to see the values of dim.x, dim.y and this is confirmed. Furthermore when I stretch the gauge size horizontically dim.x remains the same and dim.y increases and the other way round if stretched vertically! Am I missing something obvious here? Michael Frantzeskakis

Share this post


Link to post
Share on other sites
Help AVSIM continue to serve you!
Please donate today!

Hello Michael.First off let me warn you that although I have done a half-dozen vector gauges up to now (none published yet), I am a begginer, as you are.I have never encountered such a problem, but might be able to shine some light, maybe ;-).First of all, what Pens and Brushes are you using? Their thickness is also important here.Also, what is the size of the bitmap being used in the IMAGE_CREATE_DIBSECTION? This is the "vector canvas" you have to draw on, and it might be a different size than the bitmap used for background/frame.Regarding the stretching behaviour, that is indeed unique. Maybe if you answer the above questions we will be able to find out a little bit more.Also, if you don't mind, posting portions of the code regarding the above would help.

Share this post


Link to post
Share on other sites

Vector Gauges use a different graphing system than FS. 100 pixels in FS is not 100 pixels in a vector gauge. Furthermore, something at, say, location 30x30 in a vector gauge at 1024x768 resolution will be in a different position when the resolution is 800x600. I get it around that problem like this:dx = (float)dim.x / X;dy = (float)dim.y / Y;With X and Y equal to the size of the bitmap in normal pixels.Now any time you want to place something on the gauge, just multiply the x and y by dx and dy. To draw a line from 30x30 to 50x50 you would do:MoveToEx (hdc, 30*dx, 30*dy, NULL);LineTo (hdc, 50*dx, 50*dy);To make it even simpler, create functions that do it for you:void DrawLine(int new_x, int new_y){ LineTo (hdc, new_x*dx, new_y*dy);}and just call DrawLine(50,50); ;-)Matt

Share this post


Link to post
Share on other sites

Hey Matt.I prefer not to define dx and dy, and just multiply a percentage by dim.x and dim.y, as inLineTo(hdc, 0.3*dim.x, 0.65*dim.y);In that way this point will be the same inside the gauge "canvas" no matter what resolution you are at, as in when using dx or dy. The reason I prefer this is I can visualize it better this way, where the line starts and ends.But it is down to personal preference :-)

Share this post


Link to post
Share on other sites

The problem doing it that way is when you want to draw something to a specific point. I can look at an image in Paint Shop Pro and see that a line is supposed to go to a certain point. Using dx and dy, I can just multiply them by the location I want it at. Your way (although this is how I did it at first) you have to manually figure out what percentage of the canvas size it's located at. Instead of just saying 50,50, you would have to take that 50,50 and divide it by the canvas size on a calculator first. Then later when you go back to look at it, you can't really tell where it's located at. ;-)Matt

Share this post


Link to post
Share on other sites

Hey Matt.I do it old style, m8, and that's probably a bit longer, but I don't like measuring the reference image, as I suppose that is what you refer to when you say "...an image in Paint Shop Pro...". So I estimate, take a screenshot, then take the original picture of the real gauge, make it 50% transparent, and overlay that onto my gauge, to match the positioning exactly.I like the end result, but I might give your way a try :-)Oh yeah, and you can get pretty precise when your percentages have four deimal places :-).

Share this post


Link to post
Share on other sites

Fabio and Matt, thanks for your response.I am aware of the implications of gauge size, drawing canvas size, background bitmat size, sizes in the panel.cfg, screen resolution etc. The point is that regardless of these definitions, dim.x and dim.y are supposed to hold the actual viewable drawing area dimensions in pixels, so a (0,0,dim.x,dim.y) rectangle should always be on the border of the gauge as you see it in the panel.Fabio, there is no source to show you, I have just compiled and tested the FlightMap example included in the MS SDK with no changes at all in the code. I assume that this works fine with everybody else (otherwise we would have heard something) so I suppose this is not a matter of code but a problem specific to my system? After some more testing I have done by drawing as text the dim.x, dim.y values on the gauge and monitoting the results I can confirm that dim.x returns the height of the gauge (intead of the width - minus a 1 or 2 pixels) and dim.y returns exactly the double of the gauge width (instead of the height). That's why this stretching behaviour I described in my previous post occurs. Looks very strange, if anyone has any ideas, please let me know. Thanks,Michael

Share this post


Link to post
Share on other sites

I am noticing one problem with the 'dx' method proposed above. Sometimes you get a rounding error at certain resolutions.For example, in my PFD gauge I am working on, I am using this statement:Rectangle(hdc, 89 * dx, 0, 92 * dx, 19 * dy);Rectangle(hdc, 159 * dx, 0, 162 * dx, 19 * dy);to make 2 rectangles 3 px wide(dx and dy are created using the method described in this thread). Unfortunetly, at my resolution(1280x960 desktop, with FS in windowed mode) the first rectangle is a 4px wide rectangle, whilst the second rectangle is the 3 px I wanted.Oh well :)

Share this post


Link to post
Share on other sites

Hey Fred.Are your dx and dy floats or ints?Nonetheless, I have found that I can only get good accuracy regarding pixel numbers in structures I draw if my resolution is 1600x1200.

Share this post


Link to post
Share on other sites

Fabio,Long time no see :)I am getting dx and dy from:dx = (float)dim.x / 276;dy = (float)dim.y / 257;dx and dy are declared as floats.

Share this post


Link to post
Share on other sites

Fred,I don't think you need to cast dim.x and dim.y to floats before doing the division. Once you divide the integer PIXELPOINT dim.x or dim.y by the background size, which is an integer, the result will be a float anyway, usually. I use...// 238x239 = dimensions of backgroundFLOAT64 dx = dim.x / 238; FLOAT64 dy = dim.y / 239;I also understand that it's more efficient for the cpu to multiply than divide, so it might be better to actually multiply dim.x by your hand-calculated value for 1/238, or ...FLOAT64 dx = (FLOAT64)dim.x * 0.004202;Notice that dim.x is now cast to float before operation.Bill

Share this post


Link to post
Share on other sites

Bill --I tried your code snippet, and for whatever reason it corrected some of the problems I was having with the scaling issues. Some are still present, but, ahem, I might just have to deal with them. :)

Share this post


Link to post
Share on other sites

Fred, The problem is not only in calculating correctly dx and dy. The pixel coordinates in Rectangle and the other GDI functions are integer parameters so the calculated float values are truncated when converted to integers. In your code:Rectangle(hdc, 89 * dx, 0, 92 * dx, 19 * dy);Rectangle(hdc, 159 * dx, 0, 162 * dx, 19 * dy);if, for example, we assume that dx is 1.05:89*dx is 93.45 which is coverted to an integer as 93 92*dx is 96.60 => 96 so this rectangle is 96-93=3 pixels wide.For the second rectangle:159*dx=166.95 => 166162*dx=170.10 => 170width: 170-166 = 4 pixels If you want to be more accurate you could write a function to round the dx*.., dy*.. values to the closest integer before passing them to the GDI functions (or is there already a round function in C ?? )This thread has grown, but still no clues for the problem I reported in the original post :-(Anyway I can live with that by adjusting dx=dim.y/(2*width) and dy=dim.x/width, but it seems so strange that I might be the only one to have such a problem.Michael

Share this post


Link to post
Share on other sites

Michael,Post the code snippet that's giving you the problem.Bill

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this