Hi,
I draw my own custom graph and the width of the graph can vary by monitor.
I calculate the width and the number of bars to draw and then calculate the width of each bar but I have to use Floor on the division in order to round to an integer value.
This is a problem because then the total width of all bars does NOT equal the total width of the graph… and so there is a big gap to the right. And the bars aren’t as wide as they could be.
Any reason why the graphics DrawRect and FillRect couldn’t use Double instead of Integer???
because graphics routines on a monitor are restricted to the pixel resolution of said monitor…
You can light up pixel(1,1) or pixel(2,2) but there is no such a thing as pixel(1.23,1.97)… but if done properly you should never be off by more that (# of bars)-1 pixels… and even so, you should use an algorithm that interpolates across your chart, meaning it adds a pixel or two to the width of some bars, which spreads the “error” across the entire screen instead of one big glaring gap.
example… you calculate the width to be 50.5 pixels
bar #1 is from 0 to 50, bar #2 is from 51 to 101, then 101 to 151, then 152 to 202 etc.
OK I guess this interpolation is not what I am doing… I am using this code to calc the width of each bar and then other code draws each bar with DrawRect and colors it with FillRect.
if (g.Width - (XintInc * numBars)) >= numBars Then
XintInc = XintInc + Floor((g.Width - (XintInc * numBars)) / numBars)
End If
This does leave a big gap on the right side of the bars.
Note that when I have done this, I keep everything in doubles and round just before I call and draw functions. I assumed that’s what you were doing when I suggested rounding.
Take the width, divide it by the number of segments you want to come up with your segwidth and/or segheight values.
Then interate I from 0 to segnum
Multiply i by segwidth/height and round the result before drawing.
Your drawn segments will be slightly different widths but will likely look ok overall. The width will work out to the exact number you’re looking for because you started with it.
I’ve done this for a number of drawing applications and it works well.
For OS X and iOS there is. All the underlying Core Graphics draw functions take floating point coordinates and when plotting curves the difference is noticeable.
you can sorta get at these subpixel coordinates in Xojo by playing with ScaleXY. Set it to 0.1 and your draw coordinates now represent 1/10th pixel. In this code, because the effectively 1 pixel wide line is drawn between pixels it’s antialiased to cover 2 pixels wide at lower intensity.
[code]Sub Paint(g As Graphics, areas() As REALbasic.Rect)
For 6 bars and 122 pixels of width (example of course) that won’t divide evenly. So first, start with the minimum bar width:
Const NumBars = 6
Const AvailableWidth = 122
Dim BarWidth As Integer = Floor(AvailableWidth / NumBars) // 20
Then find the remainder
Dim RemainingPixels As Integer = AvailableWidth - (NumBars * BarWidth) // 2
What this RemainingPixels variable tells us is the number of bars that need 1 additional pixel. So in this example, the first 2 bars will need 1 extra pixel. Bars 1 and 2 should be 21, while 3-6 should be 20.
actually… no… while the IOS graphics routines take floating point values, the hardware is still “integer”… it just removes the burden of the calculations we are discussing away from the developer
Well, this is an example where having double the amount of pixels with HiDPI support can make things significantly easier. Not exactly fractional pixels, but there are indeed two pixels per “1/72th inch” point.
Dave No, fractional positions ARE supported and they are represented by grey scale or intensity variations. Look closely at small fonts and you can see the effect of fractional pixels.
Anti Aliasing is NOT fractional pixels. It is a way to reduce jaggies and give an impression of smoothness by blurring somewhat the edge of oblique lines and curves. In Windows Cleartype, in addition to grey pixels, yellow and blue ones are used to improve legibility by color contrast.
CGContextSetAllowsFontSubpixelPositioning is allowed only if the font is antialiased, so indeed some blurry rendition can produce an image of text that looks like at a fraction of the pixel.
But yet, in the example of the OP, there is no way to draw half a pixel in a graph.