help on algorithm (HUD BAR)

• 01-11-2012
Swoorup
help on algorithm (HUD BAR)
Hello I am trying to draw a bar which has curves on its either side but the curves are seem imperfect. Can anyone help me on the following code?

barValue gives the amount of value the bar should have with respect to the width.
the Bar should not be drawn fully but upto the value of barValue.
The posinfo contains the coordinates of the line to be drawn.
The drawTexture draws on to the screen take the line texture address, posinfo address and color addres.

Code:

```define LINE_WIDTH 0.5f void drawHUDBar(int texNum,float X,float Y,float width,float height,float barValue) {         float newYScale=0.0f;         float radius=height/2.0f;         float l;         for ( l=0.0f;l<=barValue;l=l+LINE_WIDTH)         {   if (l<=radius)   {           newYScale=sqrtf(radius*radius-(radius-l)*(radius-l));           posInfo.x1=X+l;           posInfo.y1=Y+radius-newYScale;           posInfo.x2=posInfo.x1+LINE_WIDTH;           posInfo.y2=Y+radius+newYScale;           drawTexture(&texturePtr,&posInfo,&default_color);   }   else if (l<(width-radius))   {           posInfo.x1=X+radius;           posInfo.y1=Y;           if (barValue<=(width-radius)) posInfo.x2=posInfo.x1+barValue-radius;           else posInfo.x2=posInfo.x1+width-2*radius;           posInfo.y2=Y+2*radius;           drawTexture(&texturePtr,&posInfo,&default_color);           l=width-radius-LINE_WIDTH;   }   else if (l>=(width-radius))   {           newYScale=sqrtf(radius*radius-(radius-width+l)*(radius-width+l));           posInfo.x1=X+l;           posInfo.y1=Y+radius-newYScale;           posInfo.x2=posInfo.x1+LINE_WIDTH;           posInfo.y2=Y+radius+newYScale;           drawTexture(&texturePtr,&posInfo,&default_color);   }           } }```
If there is better or faster algorithm please do post
• 01-11-2012
Salem
Take a picture of the screen (say print-screen), save it, edit it to show what you mean, then post it as an attachment.

I see plenty of scope for rounding errors.

But if you want symmetry, why don't you just draw half of it, and then just perform a reflection on the calculated points, rather than calculating them all again.
• 01-12-2012
VirtualAce
Why don't you just use a bitmap of the curve and then interpolate across the bitmap to show different portions of it? With some alpha blending you can achieve some pretty cool effects like this all the while using textures. The upside to this is that it is much simpler to use textures for this than vector graphics or some other approach.
• 01-12-2012
Swoorup
They seem to be fine when the height is increased but if the height is small if is kind of imperfect.
I have modified them to work properly with every resolutions by putting a resolution multiplier.
http://img638.imageshack.us/img638/307/82086393.jpg
• 01-13-2012
bernt
It looks to me like the endpoints of the lines you draw get rounded to the nearest pixel.

I think that rounding "newYScale" to the nearest integer (perhaps nearest 1/2) will do the trick - at the very least it would make the bars symmetric.
Or, if you have the option of turning on multisample AA with whatever you use for graphics, that would help as well.
• 01-13-2012
Swoorup
Code:

```int round2int(float f) {   int a;   a=(int)f;   if(f-a>0.5)return a+1;   if(f-a<-0.5)return a-1;   return a; } void HUDstyle_1(int texNum,float X,float Y,float width,float height,float barValue) {         float newYScale=0.0f;         float radius=height/2.0f;         float l;         for ( l=0.0f;l<=barValue;l=l+LINE_WIDTH)         {                 if (l<=radius)                 {                         newYScale=round2int(sqrtf(radius*radius-(radius-l)*(radius-l)));                         posInfo.x=X+l;                         posInfo.y=Y+radius-newYScale;                         posInfo.w=posInfo.x+LINE_WIDTH;                         posInfo.h=Y+radius+newYScale;                         drawTexture(&texturePtr,&posInfo,&default_color);                 }                 else if (l<(width-radius))                 {                         posInfo.x=X+radius;                         posInfo.y=Y;                         if (barValue<=(width-radius)) posInfo.w=posInfo.x+barValue-radius;                         else posInfo.w=posInfo.x+width-2*radius;                         posInfo.h=Y+2*radius;                         drawTexture(&texturePtr,&posInfo,&default_color);                         l=width-radius-LINE_WIDTH;                 }                 else if (l>=(width-radius))                 {                         newYScale=round2int(sqrtf(radius*radius-(radius-width+l)*(radius-width+l)));                         posInfo.x=X+l;                         posInfo.y=Y+radius-newYScale;                         posInfo.w=posInfo.x+LINE_WIDTH;                         posInfo.h=Y+radius+newYScale;                         drawTexture(&texturePtr,&posInfo,&default_color);                 }                         } }```
I am now using this function and thank you the symmetry is now perfect but still the curve is not as it should be.
• 01-13-2012
VirtualAce
Ok now I see what you are trying to do and there is a much simpler way. Go to Blender and create a model 1 unit by 1 unit that is the bar you want. Now load that and render it on your screen after doing the standard SRT transformations. If you want to do this manually your model is a rectangle surrounded on either side by 2 triangle fans. That would be a much simpler way to render this.
• 01-13-2012
bernt
Quote:

Originally Posted by VirtualAce
If you want to do this manually your model is a rectangle surrounded on either side by 2 triangle fans. That would be a much simpler way to render this.

The problem here is that if the amount that needs to be shaded in is less than or higher than a certain amount (see attachment), using triangle fans is difficult.

Attachment 11337

I think that your alpha blending route is probably the best one to pursue. One could draw the entire capsule shape (rect + triangle fans would work here) onto a texture, then simply draw a rectangle with that texture as the alpha mask. ie,

Attachment 11338
• 01-13-2012
VirtualAce
Indeed. That is what I was referring to when I mentioned the alpha blending. The same tricks can be applied to draw round controls and mini-maps on your screen. Just alpha out the portions that you do not want to see.