Thread: help on algorithm (HUD BAR)

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    83

    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

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    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.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    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.

  4. #4
    Registered User
    Join Date
    Nov 2011
    Posts
    83
    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

  5. #5
    Just a pushpin. bernt's Avatar
    Join Date
    May 2009
    Posts
    426
    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.
    Consider this post signed

  6. #6
    Registered User
    Join Date
    Nov 2011
    Posts
    83
    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.

  7. #7
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    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.

  8. #8
    Just a pushpin. bernt's Avatar
    Join Date
    May 2009
    Posts
    426
    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.

    help on algorithm (HUD BAR)-edgecase-png

    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,

    help on algorithm (HUD BAR)-mask-png
    Consider this post signed

  9. #9
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. algorithm
    By osheghi in forum C++ Programming
    Replies: 0
    Last Post: 05-01-2009, 10:07 AM
  2. An algorithm about C/C++
    By umutdogan in forum C++ Programming
    Replies: 18
    Last Post: 10-06-2003, 03:41 PM
  3. C++ algorithm help
    By Gene126 in forum C++ Programming
    Replies: 8
    Last Post: 10-10-2002, 03:17 PM
  4. Need Help for an algorithm.....
    By arvindkr in forum C++ Programming
    Replies: 0
    Last Post: 08-24-2002, 03:45 AM
  5. my grandfather's chess algorithm can beat your grandfather's chess algorithm...
    By doubleanti in forum A Brief History of Cprogramming.com
    Replies: 22
    Last Post: 08-17-2001, 06:52 PM